Compare commits
60 Commits
v1.0.1
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
4744ec27b8 | |||
b1782e50d7 | |||
b03deb63a9 | |||
26745d3752 | |||
9f67faf00f | |||
08d0f33416 | |||
dca23ad451 | |||
76307bf0f6 | |||
ba47b49609 | |||
2be2960897 | |||
8ede7eed87 | |||
42268a4a93 | |||
22dd6c553d | |||
f531419b53 | |||
5a4ecc5402 | |||
90e8e1faf9 | |||
3b2afc93dc | |||
9649ec14f5 | |||
27e830b73e | |||
0c12d8a1c8 | |||
152e7a48e4 | |||
4319bc47f6 | |||
186edecd6c | |||
de5cffee1d | |||
135eb1dd85 | |||
7a55617a0e | |||
5d073d690c | |||
67110e02ba | |||
1324428a9a | |||
fd4c3350ae | |||
cc32993e9e | |||
b76849596f | |||
c9d0423023 | |||
57e95c5dfe | |||
092009035b | |||
547a516c30 | |||
3033fd2e75 | |||
d5a6569102 | |||
f1f128e3c9 | |||
27fdec5cb9 | |||
a1051f3bf1 | |||
c627ea807c | |||
4b216e9d9b | |||
2bebd89aa2 | |||
be383cf30d | |||
6d1f71e55a | |||
24259e7d21 | |||
c16cff9805 | |||
7cb3453c36 | |||
2a9114d1af | |||
2c46a72680 | |||
ceb34eb2e6 | |||
90c018566c | |||
a6b5412c55 | |||
081ed44a1d | |||
8ab23366fb | |||
2052c30acd | |||
a786b12b68 | |||
0db5882a12 | |||
5a408187d4 |
5
.github/workflows/test.yaml
vendored
5
.github/workflows/test.yaml
vendored
@ -4,7 +4,7 @@ name: test
|
||||
on: ["push", "pull_request"]
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.16"
|
||||
GO_VERSION: "1.17"
|
||||
LINUX_ARCHES: "amd64 386 arm arm64 s390x mips64le ppc64le"
|
||||
|
||||
jobs:
|
||||
@ -35,6 +35,9 @@ jobs:
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install linux-modules-extra-$(uname -r)
|
||||
- name: Install nftables
|
||||
run: sudo apt-get install nftables
|
||||
|
||||
- name: setup go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
|
23
go.mod
23
go.mod
@ -1,6 +1,6 @@
|
||||
module github.com/containernetworking/plugins
|
||||
|
||||
go 1.16
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/Microsoft/hcsshim v0.8.20
|
||||
@ -13,13 +13,28 @@ require (
|
||||
github.com/d2g/dhcp4client v1.0.0
|
||||
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5
|
||||
github.com/godbus/dbus/v5 v5.0.4
|
||||
github.com/j-keck/arping v1.0.2
|
||||
github.com/mattn/go-shellwords v1.0.12
|
||||
github.com/networkplumbing/go-nft v0.2.0
|
||||
github.com/onsi/ginkgo v1.16.4
|
||||
github.com/onsi/gomega v1.15.0
|
||||
github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5
|
||||
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.4.17 // indirect
|
||||
github.com/containerd/cgroups v1.0.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
|
||||
github.com/nxadm/tail v1.4.8 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect
|
||||
go.opencensus.io v0.22.3 // indirect
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 // indirect
|
||||
golang.org/x/text v0.3.6 // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
16
go.sum
16
go.sum
@ -178,8 +178,6 @@ github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNR
|
||||
github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/cni v1.0.0 h1:9VJe1a5uKtdeJIHC/UvbTweracOh6GafT0nfbEGVcQ0=
|
||||
github.com/containernetworking/cni v1.0.0/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y=
|
||||
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 v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM=
|
||||
@ -375,8 +373,6 @@ github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
|
||||
github.com/j-keck/arping v1.0.2 h1:hlLhuXgQkzIJTZuhMigvG/CuSkaspeaD9hRDk2zuiMI=
|
||||
github.com/j-keck/arping v1.0.2/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
@ -438,6 +434,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
||||
github.com/networkplumbing/go-nft v0.2.0 h1:eKapmyVUt/3VGfhYaDos5yeprm+LPt881UeksmKKZHY=
|
||||
github.com/networkplumbing/go-nft v0.2.0/go.mod h1:HnnM+tYvlGAsMU7yoYwXEVLLiDW9gdMmb5HoGcwpuQs=
|
||||
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=
|
||||
@ -567,8 +565,9 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
||||
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/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
@ -599,6 +598,7 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yuin/goldmark v1.1.27/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/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
||||
@ -659,6 +659,7 @@ 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.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -694,6 +695,7 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@ -710,6 +712,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
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=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -771,7 +774,9 @@ golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/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-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
@ -826,6 +831,7 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs
|
||||
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-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
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=
|
||||
|
@ -36,9 +36,8 @@ var (
|
||||
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,
|
||||
PeerNamespace: netlink.NsFd(int(hostNS.Fd())),
|
||||
@ -107,7 +106,7 @@ func makeVeth(name, vethPeerName string, mtu int, mac string, hostNS ns.NetNS) (
|
||||
// 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)
|
||||
}
|
||||
@ -146,10 +145,6 @@ func SetupVethWithName(contVethName, hostVethName string, mtu int, contVethMac s
|
||||
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)
|
||||
}
|
||||
|
||||
var hostVeth netlink.Link
|
||||
err = hostNS.Do(func(_ ns.NetNS) error {
|
||||
hostVeth, err = netlink.LinkByName(hostVethName)
|
||||
|
@ -1,3 +1,4 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
// Copyright 2016 CNI authors
|
||||
|
@ -43,10 +43,6 @@ func ConfigureIface(ifName string, res *current.Result) error {
|
||||
return fmt.Errorf("failed to lookup %q: %v", ifName, err)
|
||||
}
|
||||
|
||||
if err := netlink.LinkSetUp(link); err != nil {
|
||||
return fmt.Errorf("failed to set %q UP: %v", ifName, err)
|
||||
}
|
||||
|
||||
var v4gw, v6gw net.IP
|
||||
var has_enabled_ipv6 bool = false
|
||||
for _, ipc := range res.IPs {
|
||||
@ -99,6 +95,10 @@ func ConfigureIface(ifName string, res *current.Result) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := netlink.LinkSetUp(link); err != nil {
|
||||
return fmt.Errorf("failed to set %q UP: %v", ifName, err)
|
||||
}
|
||||
|
||||
if v6gw != nil {
|
||||
ip.SettleAddresses(ifName, 10)
|
||||
}
|
||||
|
27
pkg/link/link_suite_test.go
Normal file
27
pkg/link/link_suite_test.go
Normal file
@ -0,0 +1,27 @@
|
||||
// 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 link_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestIp(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "pkg/link")
|
||||
}
|
245
pkg/link/spoofcheck.go
Normal file
245
pkg/link/spoofcheck.go
Normal file
@ -0,0 +1,245 @@
|
||||
// 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 link
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/networkplumbing/go-nft/nft"
|
||||
"github.com/networkplumbing/go-nft/nft/schema"
|
||||
)
|
||||
|
||||
const (
|
||||
natTableName = "nat"
|
||||
preRoutingBaseChainName = "PREROUTING"
|
||||
)
|
||||
|
||||
type NftConfigurer interface {
|
||||
Apply(*nft.Config) error
|
||||
Read() (*nft.Config, error)
|
||||
}
|
||||
|
||||
type SpoofChecker struct {
|
||||
iface string
|
||||
macAddress string
|
||||
refID string
|
||||
configurer NftConfigurer
|
||||
}
|
||||
|
||||
type defaultNftConfigurer struct{}
|
||||
|
||||
func (_ defaultNftConfigurer) Apply(cfg *nft.Config) error {
|
||||
return nft.ApplyConfig(cfg)
|
||||
}
|
||||
|
||||
func (_ defaultNftConfigurer) Read() (*nft.Config, error) {
|
||||
return nft.ReadConfig()
|
||||
}
|
||||
|
||||
func NewSpoofChecker(iface, macAddress, refID string) *SpoofChecker {
|
||||
return NewSpoofCheckerWithConfigurer(iface, macAddress, refID, defaultNftConfigurer{})
|
||||
}
|
||||
|
||||
func NewSpoofCheckerWithConfigurer(iface, macAddress, refID string, configurer NftConfigurer) *SpoofChecker {
|
||||
return &SpoofChecker{iface, macAddress, refID, configurer}
|
||||
}
|
||||
|
||||
// Setup applies nftables configuration to restrict traffic
|
||||
// from the provided interface. Only traffic with the mentioned mac address
|
||||
// is allowed to pass, all others are blocked.
|
||||
// The configuration follows the format libvirt and ebtables implemented, allowing
|
||||
// extensions to the rules in the future.
|
||||
// refID is used to label the rules with a unique comment, identifying the rule-set.
|
||||
//
|
||||
// In order to take advantage of the nftables configuration change atomicity, the
|
||||
// following steps are taken to apply the configuration:
|
||||
// - Declare the table and chains (they will be created in case not present).
|
||||
// - Apply the rules, while first flushing the iface/mac specific regular chain rules.
|
||||
// Two transactions are used because the flush succeeds only if the table/chain it targets
|
||||
// exists. This avoids the need to query the existing state and acting upon it (a raceful pattern).
|
||||
// Although two transactions are taken place, only the 2nd one where the rules
|
||||
// are added has a real impact on the system.
|
||||
func (sc *SpoofChecker) Setup() error {
|
||||
baseConfig := nft.NewConfig()
|
||||
|
||||
baseConfig.AddTable(&schema.Table{Family: schema.FamilyBridge, Name: natTableName})
|
||||
|
||||
baseConfig.AddChain(sc.baseChain())
|
||||
ifaceChain := sc.ifaceChain()
|
||||
baseConfig.AddChain(ifaceChain)
|
||||
macChain := sc.macChain(ifaceChain.Name)
|
||||
baseConfig.AddChain(macChain)
|
||||
|
||||
if err := sc.configurer.Apply(baseConfig); err != nil {
|
||||
return fmt.Errorf("failed to setup spoof-check: %v", err)
|
||||
}
|
||||
|
||||
rulesConfig := nft.NewConfig()
|
||||
|
||||
rulesConfig.FlushChain(ifaceChain)
|
||||
rulesConfig.FlushChain(macChain)
|
||||
|
||||
rulesConfig.AddRule(sc.matchIfaceJumpToChainRule(preRoutingBaseChainName, ifaceChain.Name))
|
||||
rulesConfig.AddRule(sc.jumpToChainRule(ifaceChain.Name, macChain.Name))
|
||||
rulesConfig.AddRule(sc.matchMacRule(macChain.Name))
|
||||
rulesConfig.AddRule(sc.dropRule(macChain.Name))
|
||||
|
||||
if err := sc.configurer.Apply(rulesConfig); err != nil {
|
||||
return fmt.Errorf("failed to setup spoof-check: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Teardown removes the interface and mac-address specific chains and their rules.
|
||||
// The table and base-chain are expected to survive while the base-chain rule that matches the
|
||||
// interface is removed.
|
||||
func (sc *SpoofChecker) Teardown() error {
|
||||
ifaceChain := sc.ifaceChain()
|
||||
currentConfig, ifaceMatchRuleErr := sc.configurer.Read()
|
||||
if ifaceMatchRuleErr == nil {
|
||||
expectedRuleToFind := sc.matchIfaceJumpToChainRule(preRoutingBaseChainName, ifaceChain.Name)
|
||||
// It is safer to exclude the statement matching, avoiding cases where a current statement includes
|
||||
// additional default entries (e.g. counters).
|
||||
ruleToFindExcludingStatements := *expectedRuleToFind
|
||||
ruleToFindExcludingStatements.Expr = nil
|
||||
rules := currentConfig.LookupRule(&ruleToFindExcludingStatements)
|
||||
if len(rules) > 0 {
|
||||
c := nft.NewConfig()
|
||||
for _, rule := range rules {
|
||||
c.DeleteRule(rule)
|
||||
}
|
||||
if err := sc.configurer.Apply(c); err != nil {
|
||||
ifaceMatchRuleErr = fmt.Errorf("failed to delete iface match rule: %v", err)
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "spoofcheck/teardown: unable to detect iface match rule for deletion: %+v", expectedRuleToFind)
|
||||
}
|
||||
}
|
||||
|
||||
regularChainsConfig := nft.NewConfig()
|
||||
regularChainsConfig.DeleteChain(ifaceChain)
|
||||
regularChainsConfig.DeleteChain(sc.macChain(ifaceChain.Name))
|
||||
|
||||
var regularChainsErr error
|
||||
if err := sc.configurer.Apply(regularChainsConfig); err != nil {
|
||||
regularChainsErr = fmt.Errorf("failed to delete regular chains: %v", err)
|
||||
}
|
||||
|
||||
if ifaceMatchRuleErr != nil || regularChainsErr != nil {
|
||||
return fmt.Errorf("failed to teardown spoof-check: %v, %v", ifaceMatchRuleErr, regularChainsErr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sc *SpoofChecker) matchIfaceJumpToChainRule(chain, toChain string) *schema.Rule {
|
||||
return &schema.Rule{
|
||||
Family: schema.FamilyBridge,
|
||||
Table: natTableName,
|
||||
Chain: chain,
|
||||
Expr: []schema.Statement{
|
||||
{Match: &schema.Match{
|
||||
Op: schema.OperEQ,
|
||||
Left: schema.Expression{RowData: []byte(`{"meta":{"key":"iifname"}}`)},
|
||||
Right: schema.Expression{String: &sc.iface},
|
||||
}},
|
||||
{Verdict: schema.Verdict{Jump: &schema.ToTarget{Target: toChain}}},
|
||||
},
|
||||
Comment: ruleComment(sc.refID),
|
||||
}
|
||||
}
|
||||
|
||||
func (sc *SpoofChecker) jumpToChainRule(chain, toChain string) *schema.Rule {
|
||||
return &schema.Rule{
|
||||
Family: schema.FamilyBridge,
|
||||
Table: natTableName,
|
||||
Chain: chain,
|
||||
Expr: []schema.Statement{
|
||||
{Verdict: schema.Verdict{Jump: &schema.ToTarget{Target: toChain}}},
|
||||
},
|
||||
Comment: ruleComment(sc.refID),
|
||||
}
|
||||
}
|
||||
|
||||
func (sc *SpoofChecker) matchMacRule(chain string) *schema.Rule {
|
||||
return &schema.Rule{
|
||||
Family: schema.FamilyBridge,
|
||||
Table: natTableName,
|
||||
Chain: chain,
|
||||
Expr: []schema.Statement{
|
||||
{Match: &schema.Match{
|
||||
Op: schema.OperEQ,
|
||||
Left: schema.Expression{Payload: &schema.Payload{
|
||||
Protocol: schema.PayloadProtocolEther,
|
||||
Field: schema.PayloadFieldEtherSAddr,
|
||||
}},
|
||||
Right: schema.Expression{String: &sc.macAddress},
|
||||
}},
|
||||
{Verdict: schema.Verdict{SimpleVerdict: schema.SimpleVerdict{Return: true}}},
|
||||
},
|
||||
Comment: ruleComment(sc.refID),
|
||||
}
|
||||
}
|
||||
|
||||
func (sc *SpoofChecker) dropRule(chain string) *schema.Rule {
|
||||
macRulesIndex := nft.NewRuleIndex()
|
||||
return &schema.Rule{
|
||||
Family: schema.FamilyBridge,
|
||||
Table: natTableName,
|
||||
Chain: chain,
|
||||
Index: macRulesIndex.Next(),
|
||||
Expr: []schema.Statement{
|
||||
{Verdict: schema.Verdict{SimpleVerdict: schema.SimpleVerdict{Drop: true}}},
|
||||
},
|
||||
Comment: ruleComment(sc.refID),
|
||||
}
|
||||
}
|
||||
|
||||
func (_ *SpoofChecker) baseChain() *schema.Chain {
|
||||
chainPriority := -300
|
||||
return &schema.Chain{
|
||||
Family: schema.FamilyBridge,
|
||||
Table: natTableName,
|
||||
Name: preRoutingBaseChainName,
|
||||
Type: schema.TypeFilter,
|
||||
Hook: schema.HookPreRouting,
|
||||
Prio: &chainPriority,
|
||||
Policy: schema.PolicyAccept,
|
||||
}
|
||||
}
|
||||
|
||||
func (sc *SpoofChecker) ifaceChain() *schema.Chain {
|
||||
ifaceChainName := "cni-br-iface-" + sc.refID
|
||||
return &schema.Chain{
|
||||
Family: schema.FamilyBridge,
|
||||
Table: natTableName,
|
||||
Name: ifaceChainName,
|
||||
}
|
||||
}
|
||||
|
||||
func (_ *SpoofChecker) macChain(ifaceChainName string) *schema.Chain {
|
||||
macChainName := ifaceChainName + "-mac"
|
||||
return &schema.Chain{
|
||||
Family: schema.FamilyBridge,
|
||||
Table: natTableName,
|
||||
Name: macChainName,
|
||||
}
|
||||
}
|
||||
|
||||
func ruleComment(id string) string {
|
||||
const refIDPrefix = "macspoofchk-"
|
||||
return refIDPrefix + id
|
||||
}
|
297
pkg/link/spoofcheck_test.go
Normal file
297
pkg/link/spoofcheck_test.go
Normal file
@ -0,0 +1,297 @@
|
||||
// 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 link_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/networkplumbing/go-nft/nft"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/containernetworking/plugins/pkg/link"
|
||||
)
|
||||
|
||||
var _ = Describe("spoofcheck", func() {
|
||||
iface := "net0"
|
||||
mac := "02:00:00:00:12:34"
|
||||
id := "container99-net1"
|
||||
|
||||
Context("setup", func() {
|
||||
It("succeeds", func() {
|
||||
c := configurerStub{}
|
||||
sc := link.NewSpoofCheckerWithConfigurer(iface, mac, id, &c)
|
||||
Expect(sc.Setup()).To(Succeed())
|
||||
|
||||
assertExpectedTableAndChainsInSetupConfig(c)
|
||||
assertExpectedRulesInSetupConfig(c)
|
||||
})
|
||||
|
||||
It("fails to setup config when 1st apply is unsuccessful (declare table and chains)", func() {
|
||||
c := &configurerStub{failFirstApplyConfig: true}
|
||||
sc := link.NewSpoofCheckerWithConfigurer(iface, mac, id, c)
|
||||
Expect(sc.Setup()).To(MatchError("failed to setup spoof-check: " + errorFirstApplyText))
|
||||
})
|
||||
|
||||
It("fails to setup config when 2nd apply is unsuccessful (flush and add the rules)", func() {
|
||||
c := &configurerStub{failSecondApplyConfig: true}
|
||||
sc := link.NewSpoofCheckerWithConfigurer(iface, mac, id, c)
|
||||
Expect(sc.Setup()).To(MatchError("failed to setup spoof-check: " + errorSecondApplyText))
|
||||
})
|
||||
})
|
||||
|
||||
Context("teardown", func() {
|
||||
It("succeeds", func() {
|
||||
existingConfig := nft.NewConfig()
|
||||
existingConfig.FromJSON([]byte(rowConfigWithRulesOnly()))
|
||||
c := configurerStub{readConfig: existingConfig}
|
||||
|
||||
sc := link.NewSpoofCheckerWithConfigurer("", "", id, &c)
|
||||
Expect(sc.Teardown()).To(Succeed())
|
||||
|
||||
assertExpectedBaseChainRuleDeletionInTeardownConfig(c)
|
||||
assertExpectedRegularChainsDeletionInTeardownConfig(c)
|
||||
})
|
||||
|
||||
It("fails, 1st apply is unsuccessful (delete iface match rule)", func() {
|
||||
config := nft.NewConfig()
|
||||
config.FromJSON([]byte(rowConfigWithRulesOnly()))
|
||||
c := &configurerStub{applyConfig: []*nft.Config{config}, readConfig: config, failFirstApplyConfig: true}
|
||||
sc := link.NewSpoofCheckerWithConfigurer("", "", id, c)
|
||||
Expect(sc.Teardown()).To(MatchError(fmt.Sprintf(
|
||||
"failed to teardown spoof-check: failed to delete iface match rule: %s, <nil>", errorFirstApplyText,
|
||||
)))
|
||||
})
|
||||
|
||||
It("fails, read current config is unsuccessful", func() {
|
||||
config := nft.NewConfig()
|
||||
config.FromJSON([]byte(rowConfigWithRulesOnly()))
|
||||
c := &configurerStub{applyConfig: []*nft.Config{config}, readConfig: config, failReadConfig: true}
|
||||
sc := link.NewSpoofCheckerWithConfigurer("", "", id, c)
|
||||
Expect(sc.Teardown()).To(MatchError(fmt.Sprintf(
|
||||
"failed to teardown spoof-check: %s, <nil>", errorReadText,
|
||||
)))
|
||||
})
|
||||
|
||||
It("fails, 2nd apply is unsuccessful (delete the regular chains)", func() {
|
||||
config := nft.NewConfig()
|
||||
config.FromJSON([]byte(rowConfigWithRulesOnly()))
|
||||
c := &configurerStub{applyConfig: []*nft.Config{config}, readConfig: config, failSecondApplyConfig: true}
|
||||
sc := link.NewSpoofCheckerWithConfigurer("", "", id, c)
|
||||
Expect(sc.Teardown()).To(MatchError(fmt.Sprintf(
|
||||
"failed to teardown spoof-check: <nil>, failed to delete regular chains: %s", errorSecondApplyText,
|
||||
)))
|
||||
})
|
||||
|
||||
It("fails, both applies are unsuccessful", func() {
|
||||
config := nft.NewConfig()
|
||||
config.FromJSON([]byte(rowConfigWithRulesOnly()))
|
||||
c := &configurerStub{
|
||||
applyConfig: []*nft.Config{config},
|
||||
readConfig: config,
|
||||
failFirstApplyConfig: true,
|
||||
failSecondApplyConfig: true,
|
||||
}
|
||||
sc := link.NewSpoofCheckerWithConfigurer("", "", id, c)
|
||||
Expect(sc.Teardown()).To(MatchError(fmt.Sprintf(
|
||||
"failed to teardown spoof-check: "+
|
||||
"failed to delete iface match rule: %s, "+
|
||||
"failed to delete regular chains: %s",
|
||||
errorFirstApplyText, errorSecondApplyText,
|
||||
)))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
func assertExpectedRegularChainsDeletionInTeardownConfig(action configurerStub) {
|
||||
deleteRegularChainRulesJsonConfig, err := action.applyConfig[1].ToJSON()
|
||||
ExpectWithOffset(1, err).NotTo(HaveOccurred())
|
||||
|
||||
expectedDeleteRegularChainRulesJsonConfig := `
|
||||
{"nftables": [
|
||||
{"delete": {"chain": {
|
||||
"family": "bridge",
|
||||
"table": "nat",
|
||||
"name": "cni-br-iface-container99-net1"
|
||||
}}},
|
||||
{"delete": {"chain": {
|
||||
"family": "bridge",
|
||||
"table": "nat",
|
||||
"name": "cni-br-iface-container99-net1-mac"
|
||||
}}}
|
||||
]}`
|
||||
|
||||
ExpectWithOffset(1, string(deleteRegularChainRulesJsonConfig)).To(MatchJSON(expectedDeleteRegularChainRulesJsonConfig))
|
||||
}
|
||||
|
||||
func assertExpectedBaseChainRuleDeletionInTeardownConfig(action configurerStub) {
|
||||
deleteBaseChainRuleJsonConfig, err := action.applyConfig[0].ToJSON()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
expectedDeleteIfaceMatchRuleJsonConfig := `
|
||||
{"nftables": [
|
||||
{"delete": {"rule": {
|
||||
"family": "bridge",
|
||||
"table": "nat",
|
||||
"chain": "PREROUTING",
|
||||
"expr": [
|
||||
{"match": {
|
||||
"op": "==",
|
||||
"left": {"meta": {"key": "iifname"}},
|
||||
"right": "net0"
|
||||
}},
|
||||
{"jump": {"target": "cni-br-iface-container99-net1"}}
|
||||
],
|
||||
"comment": "macspoofchk-container99-net1"
|
||||
}}}
|
||||
]}`
|
||||
Expect(string(deleteBaseChainRuleJsonConfig)).To(MatchJSON(expectedDeleteIfaceMatchRuleJsonConfig))
|
||||
}
|
||||
|
||||
func rowConfigWithRulesOnly() string {
|
||||
return `
|
||||
{"nftables":[
|
||||
{"rule":{"family":"bridge","table":"nat","chain":"PREROUTING",
|
||||
"expr":[
|
||||
{"match":{"op":"==","left":{"meta":{"key":"iifname"}},"right":"net0"}},
|
||||
{"jump":{"target":"cni-br-iface-container99-net1"}}
|
||||
],
|
||||
"comment":"macspoofchk-container99-net1"}},
|
||||
{"rule":{"family":"bridge","table":"nat","chain":"cni-br-iface-container99-net1",
|
||||
"expr":[
|
||||
{"jump":{"target":"cni-br-iface-container99-net1-mac"}}
|
||||
],
|
||||
"comment":"macspoofchk-container99-net1"}},
|
||||
{"rule":{"family":"bridge","table":"nat","chain":"cni-br-iface-container99-net1-mac",
|
||||
"expr":[
|
||||
{"match":{
|
||||
"op":"==",
|
||||
"left":{"payload":{"protocol":"ether","field":"saddr"}},
|
||||
"right":"02:00:00:00:12:34"
|
||||
}},
|
||||
{"return":null}
|
||||
],
|
||||
"comment":"macspoofchk-container99-net1"}},
|
||||
{"rule":{"family":"bridge","table":"nat","chain":"cni-br-iface-container99-net1-mac",
|
||||
"expr":[{"drop":null}],
|
||||
"index":0,
|
||||
"comment":"macspoofchk-container99-net1"}}
|
||||
]}`
|
||||
}
|
||||
|
||||
func assertExpectedTableAndChainsInSetupConfig(c configurerStub) {
|
||||
config := c.applyConfig[0]
|
||||
jsonConfig, err := config.ToJSON()
|
||||
ExpectWithOffset(1, err).NotTo(HaveOccurred())
|
||||
|
||||
expectedConfig := `
|
||||
{"nftables": [
|
||||
{"table": {"family": "bridge", "name": "nat"}},
|
||||
{"chain": {
|
||||
"family": "bridge",
|
||||
"table": "nat",
|
||||
"name": "PREROUTING",
|
||||
"type": "filter",
|
||||
"hook": "prerouting",
|
||||
"prio": -300,
|
||||
"policy": "accept"
|
||||
}},
|
||||
{"chain": {
|
||||
"family": "bridge",
|
||||
"table": "nat",
|
||||
"name": "cni-br-iface-container99-net1"
|
||||
}},
|
||||
{"chain": {
|
||||
"family": "bridge",
|
||||
"table": "nat",
|
||||
"name": "cni-br-iface-container99-net1-mac"
|
||||
}}
|
||||
]}`
|
||||
ExpectWithOffset(1, string(jsonConfig)).To(MatchJSON(expectedConfig))
|
||||
}
|
||||
|
||||
func assertExpectedRulesInSetupConfig(c configurerStub) {
|
||||
config := c.applyConfig[1]
|
||||
jsonConfig, err := config.ToJSON()
|
||||
ExpectWithOffset(1, err).NotTo(HaveOccurred())
|
||||
|
||||
expectedConfig := `
|
||||
{"nftables":[
|
||||
{"flush":{"chain":{"family":"bridge","table":"nat","name":"cni-br-iface-container99-net1"}}},
|
||||
{"flush":{"chain":{"family":"bridge","table":"nat","name":"cni-br-iface-container99-net1-mac"}}},
|
||||
{"rule":{"family":"bridge","table":"nat","chain":"PREROUTING",
|
||||
"expr":[
|
||||
{"match":{"op":"==","left":{"meta":{"key":"iifname"}},"right":"net0"}},
|
||||
{"jump":{"target":"cni-br-iface-container99-net1"}}
|
||||
],
|
||||
"comment":"macspoofchk-container99-net1"}},
|
||||
{"rule":{"family":"bridge","table":"nat","chain":"cni-br-iface-container99-net1",
|
||||
"expr":[
|
||||
{"jump":{"target":"cni-br-iface-container99-net1-mac"}}
|
||||
],
|
||||
"comment":"macspoofchk-container99-net1"}},
|
||||
{"rule":{"family":"bridge","table":"nat","chain":"cni-br-iface-container99-net1-mac",
|
||||
"expr":[
|
||||
{"match":{
|
||||
"op":"==",
|
||||
"left":{"payload":{"protocol":"ether","field":"saddr"}},
|
||||
"right":"02:00:00:00:12:34"
|
||||
}},
|
||||
{"return":null}
|
||||
],
|
||||
"comment":"macspoofchk-container99-net1"}},
|
||||
{"rule":{"family":"bridge","table":"nat","chain":"cni-br-iface-container99-net1-mac",
|
||||
"expr":[{"drop":null}],
|
||||
"index":0,
|
||||
"comment":"macspoofchk-container99-net1"}}
|
||||
]}`
|
||||
ExpectWithOffset(1, string(jsonConfig)).To(MatchJSON(expectedConfig))
|
||||
}
|
||||
|
||||
const (
|
||||
errorFirstApplyText = "1st apply failed"
|
||||
errorSecondApplyText = "2nd apply failed"
|
||||
errorReadText = "read failed"
|
||||
)
|
||||
|
||||
type configurerStub struct {
|
||||
applyConfig []*nft.Config
|
||||
readConfig *nft.Config
|
||||
|
||||
applyCounter int
|
||||
|
||||
failFirstApplyConfig bool
|
||||
failSecondApplyConfig bool
|
||||
failReadConfig bool
|
||||
}
|
||||
|
||||
func (a *configurerStub) Apply(c *nft.Config) error {
|
||||
a.applyCounter++
|
||||
if a.failFirstApplyConfig && a.applyCounter == 1 {
|
||||
return fmt.Errorf(errorFirstApplyText)
|
||||
}
|
||||
if a.failSecondApplyConfig && a.applyCounter == 2 {
|
||||
return fmt.Errorf(errorSecondApplyText)
|
||||
}
|
||||
a.applyConfig = append(a.applyConfig, c)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *configurerStub) Read() (*nft.Config, error) {
|
||||
if a.failReadConfig {
|
||||
return nil, fmt.Errorf(errorReadText)
|
||||
}
|
||||
return a.readConfig, nil
|
||||
}
|
@ -106,8 +106,8 @@ var _ NetNS = &netNS{}
|
||||
|
||||
const (
|
||||
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/magic.h
|
||||
NSFS_MAGIC = 0x6e736673
|
||||
PROCFS_MAGIC = 0x9fa0
|
||||
NSFS_MAGIC = unix.NSFS_MAGIC
|
||||
PROCFS_MAGIC = unix.PROC_SUPER_MAGIC
|
||||
)
|
||||
|
||||
type NSPathNotExistErr struct{ msg string }
|
||||
|
@ -53,7 +53,7 @@ func NewNS() (ns.NetNS, error) {
|
||||
nsRunDir := getNsRunDir()
|
||||
|
||||
b := make([]byte, 16)
|
||||
_, err := rand.Reader.Read(b)
|
||||
_, err := rand.Read(b)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate random netns name: %v", err)
|
||||
}
|
||||
|
@ -62,8 +62,8 @@ func DeleteConntrackEntriesForDstIP(dstIP string, protocol uint8) error {
|
||||
// by the given destination port, protocol and IP family
|
||||
func DeleteConntrackEntriesForDstPort(port uint16, protocol uint8, family netlink.InetFamily) error {
|
||||
filter := &netlink.ConntrackFilter{}
|
||||
filter.AddPort(netlink.ConntrackOrigDstPort, port)
|
||||
filter.AddProtocol(protocol)
|
||||
filter.AddPort(netlink.ConntrackOrigDstPort, port)
|
||||
|
||||
_, err := netlink.ConntrackDeleteFilter(netlink.ConntrackTable, family, filter)
|
||||
if err != nil {
|
||||
|
@ -119,3 +119,21 @@ func ClearChain(ipt *iptables.IPTables, table, chain string) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// InsertUnique will add a rule to a chain if it does not already exist.
|
||||
// By default the rule is appended, unless prepend is true.
|
||||
func InsertUnique(ipt *iptables.IPTables, table, chain string, prepend bool, rule []string) error {
|
||||
exists, err := ipt.Exists(table, chain, rule...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
if prepend {
|
||||
return ipt.Insert(table, chain, 1, rule...)
|
||||
} else {
|
||||
return ipt.Append(table, chain, rule...)
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,6 @@ func Sysctl(name string, params ...string) (string, error) {
|
||||
|
||||
func getSysctl(name string) (string, error) {
|
||||
fullName := filepath.Join("/proc/sys", toNormalName(name))
|
||||
fullName = filepath.Clean(fullName)
|
||||
data, err := ioutil.ReadFile(fullName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -47,7 +46,6 @@ func getSysctl(name string) (string, error) {
|
||||
|
||||
func setSysctl(name, value string) (string, error) {
|
||||
fullName := filepath.Join("/proc/sys", toNormalName(name))
|
||||
fullName = filepath.Clean(fullName)
|
||||
if err := ioutil.WriteFile(fullName, []byte(value), 0644); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -29,13 +29,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/skel"
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
current "github.com/containernetworking/cni/pkg/types/100"
|
||||
"github.com/coreos/go-systemd/v22/activation"
|
||||
)
|
||||
|
||||
const listenFdsStart = 3
|
||||
|
||||
var errNoMoreTries = errors.New("no more tries")
|
||||
|
||||
type DHCP struct {
|
||||
@ -55,21 +52,35 @@ func newDHCP(clientTimeout, clientResendMax time.Duration) *DHCP {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: current client ID is too long. At least the container ID should not be used directly.
|
||||
// A seperate issue is necessary to ensure no breaking change is affecting other users.
|
||||
func generateClientID(containerID string, netName string, ifName string) string {
|
||||
return containerID + "/" + netName + "/" + ifName
|
||||
clientID := containerID + "/" + netName + "/" + ifName
|
||||
// defined in RFC 2132, length size can not be larger than 1 octet. So we truncate 254 to make everyone happy.
|
||||
if len(clientID) > 254 {
|
||||
clientID = clientID[0:254]
|
||||
}
|
||||
return clientID
|
||||
}
|
||||
|
||||
// Allocate acquires an IP from a DHCP server for a specified container.
|
||||
// The acquired lease will be maintained until Release() is called.
|
||||
func (d *DHCP) Allocate(args *skel.CmdArgs, result *current.Result) error {
|
||||
conf := types.NetConf{}
|
||||
conf := NetConf{}
|
||||
if err := json.Unmarshal(args.StdinData, &conf); err != nil {
|
||||
return fmt.Errorf("error parsing netconf: %v", err)
|
||||
}
|
||||
|
||||
optsRequesting, optsProviding, err := prepareOptions(args.Args, conf.IPAM.ProvideOptions, conf.IPAM.RequestOptions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clientID := generateClientID(args.ContainerID, conf.Name, args.IfName)
|
||||
hostNetns := d.hostNetnsPrefix + args.Netns
|
||||
l, err := AcquireLease(clientID, hostNetns, args.IfName, d.clientTimeout, d.clientResendMax, d.broadcast)
|
||||
l, err := AcquireLease(clientID, hostNetns, args.IfName,
|
||||
optsRequesting, optsProviding,
|
||||
d.clientTimeout, d.clientResendMax, d.broadcast)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -94,7 +105,7 @@ func (d *DHCP) Allocate(args *skel.CmdArgs, result *current.Result) error {
|
||||
// Release stops maintenance of the lease acquired in Allocate()
|
||||
// and sends a release msg to the DHCP server.
|
||||
func (d *DHCP) Release(args *skel.CmdArgs, reply *struct{}) error {
|
||||
conf := types.NetConf{}
|
||||
conf := NetConf{}
|
||||
if err := json.Unmarshal(args.StdinData, &conf); err != nil {
|
||||
return fmt.Errorf("error parsing netconf: %v", err)
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@ -36,6 +37,11 @@ import (
|
||||
const resendDelay0 = 4 * time.Second
|
||||
const resendDelayMax = 62 * time.Second
|
||||
|
||||
// To speed up the retry for first few failures, we retry without
|
||||
// backoff for a few times
|
||||
const resendFastDelay = 2 * time.Second
|
||||
const resendFastMax = 4
|
||||
|
||||
const (
|
||||
leaseStateBound = iota
|
||||
leaseStateRenewing
|
||||
@ -62,6 +68,74 @@ type DHCPLease struct {
|
||||
stopping uint32
|
||||
stop chan struct{}
|
||||
wg sync.WaitGroup
|
||||
// list of requesting and providing options and if they are necessary / their value
|
||||
optsRequesting map[dhcp4.OptionCode]bool
|
||||
optsProviding map[dhcp4.OptionCode][]byte
|
||||
}
|
||||
|
||||
var requestOptionsDefault = map[dhcp4.OptionCode]bool{
|
||||
dhcp4.OptionRouter: true,
|
||||
dhcp4.OptionSubnetMask: true,
|
||||
}
|
||||
|
||||
func prepareOptions(cniArgs string, ProvideOptions []ProvideOption, RequestOptions []RequestOption) (
|
||||
optsRequesting map[dhcp4.OptionCode]bool, optsProviding map[dhcp4.OptionCode][]byte, err error) {
|
||||
|
||||
// parse CNI args
|
||||
cniArgsParsed := map[string]string{}
|
||||
for _, argPair := range strings.Split(cniArgs, ";") {
|
||||
args := strings.SplitN(argPair, "=", 2)
|
||||
if len(args) > 1 {
|
||||
cniArgsParsed[args[0]] = args[1]
|
||||
}
|
||||
}
|
||||
|
||||
// parse providing options map
|
||||
var optParsed dhcp4.OptionCode
|
||||
optsProviding = make(map[dhcp4.OptionCode][]byte)
|
||||
for _, opt := range ProvideOptions {
|
||||
optParsed, err = parseOptionName(string(opt.Option))
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Can not parse option %q: %w", opt.Option, err)
|
||||
return
|
||||
}
|
||||
if len(opt.Value) > 0 {
|
||||
if len(opt.Value) > 255 {
|
||||
err = fmt.Errorf("value too long for option %q: %q", opt.Option, opt.Value)
|
||||
return
|
||||
}
|
||||
optsProviding[optParsed] = []byte(opt.Value)
|
||||
}
|
||||
if value, ok := cniArgsParsed[opt.ValueFromCNIArg]; ok {
|
||||
if len(value) > 255 {
|
||||
err = fmt.Errorf("value too long for option %q from CNI_ARGS %q: %q", opt.Option, opt.ValueFromCNIArg, opt.Value)
|
||||
return
|
||||
}
|
||||
optsProviding[optParsed] = []byte(value)
|
||||
}
|
||||
}
|
||||
|
||||
// parse necessary options map
|
||||
optsRequesting = make(map[dhcp4.OptionCode]bool)
|
||||
skipRequireDefault := false
|
||||
for _, opt := range RequestOptions {
|
||||
if opt.SkipDefault {
|
||||
skipRequireDefault = true
|
||||
}
|
||||
optParsed, err = parseOptionName(string(opt.Option))
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Can not parse option %q: %w", opt.Option, err)
|
||||
return
|
||||
}
|
||||
optsRequesting[optParsed] = true
|
||||
}
|
||||
for k, v := range requestOptionsDefault {
|
||||
// only set if not skipping default and this value does not exists
|
||||
if _, ok := optsRequesting[k]; !ok && !skipRequireDefault {
|
||||
optsRequesting[k] = v
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AcquireLease gets an DHCP lease and then maintains it in the background
|
||||
@ -69,15 +143,18 @@ type DHCPLease struct {
|
||||
// calling DHCPLease.Stop()
|
||||
func AcquireLease(
|
||||
clientID, netns, ifName string,
|
||||
optsRequesting map[dhcp4.OptionCode]bool, optsProviding map[dhcp4.OptionCode][]byte,
|
||||
timeout, resendMax time.Duration, broadcast bool,
|
||||
) (*DHCPLease, error) {
|
||||
errCh := make(chan error, 1)
|
||||
l := &DHCPLease{
|
||||
clientID: clientID,
|
||||
stop: make(chan struct{}),
|
||||
timeout: timeout,
|
||||
resendMax: resendMax,
|
||||
broadcast: broadcast,
|
||||
clientID: clientID,
|
||||
stop: make(chan struct{}),
|
||||
timeout: timeout,
|
||||
resendMax: resendMax,
|
||||
broadcast: broadcast,
|
||||
optsRequesting: optsRequesting,
|
||||
optsProviding: optsProviding,
|
||||
}
|
||||
|
||||
log.Printf("%v: acquiring lease", clientID)
|
||||
@ -123,6 +200,30 @@ func (l *DHCPLease) Stop() {
|
||||
l.wg.Wait()
|
||||
}
|
||||
|
||||
func (l *DHCPLease) getOptionsWithClientId() dhcp4.Options {
|
||||
opts := make(dhcp4.Options)
|
||||
opts[dhcp4.OptionClientIdentifier] = []byte(l.clientID)
|
||||
// client identifier's first byte is "type"
|
||||
newClientID := []byte{0}
|
||||
newClientID = append(newClientID, opts[dhcp4.OptionClientIdentifier]...)
|
||||
opts[dhcp4.OptionClientIdentifier] = newClientID
|
||||
return opts
|
||||
}
|
||||
|
||||
func (l *DHCPLease) getAllOptions() dhcp4.Options {
|
||||
opts := l.getOptionsWithClientId()
|
||||
|
||||
for k, v := range l.optsProviding {
|
||||
opts[k] = v
|
||||
}
|
||||
|
||||
opts[dhcp4.OptionParameterRequestList] = []byte{}
|
||||
for k := range l.optsRequesting {
|
||||
opts[dhcp4.OptionParameterRequestList] = append(opts[dhcp4.OptionParameterRequestList], byte(k))
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
func (l *DHCPLease) acquire() error {
|
||||
c, err := newDHCPClient(l.link, l.clientID, l.timeout, l.broadcast)
|
||||
if err != nil {
|
||||
@ -137,9 +238,7 @@ func (l *DHCPLease) acquire() error {
|
||||
}
|
||||
}
|
||||
|
||||
opts := make(dhcp4.Options)
|
||||
opts[dhcp4.OptionClientIdentifier] = []byte(l.clientID)
|
||||
opts[dhcp4.OptionParameterRequestList] = []byte{byte(dhcp4.OptionRouter), byte(dhcp4.OptionSubnetMask)}
|
||||
opts := l.getAllOptions()
|
||||
|
||||
pkt, err := backoffRetry(l.resendMax, func() (*dhcp4.Packet, error) {
|
||||
ok, ack, err := DhcpRequest(c, opts)
|
||||
@ -257,9 +356,7 @@ func (l *DHCPLease) renew() error {
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
opts := make(dhcp4.Options)
|
||||
opts[dhcp4.OptionClientIdentifier] = []byte(l.clientID)
|
||||
|
||||
opts := l.getOptionsWithClientId()
|
||||
pkt, err := backoffRetry(l.resendMax, func() (*dhcp4.Packet, error) {
|
||||
ok, ack, err := DhcpRenew(c, *l.ack, opts)
|
||||
switch {
|
||||
@ -288,8 +385,7 @@ func (l *DHCPLease) release() error {
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
opts := make(dhcp4.Options)
|
||||
opts[dhcp4.OptionClientIdentifier] = []byte(l.clientID)
|
||||
opts := l.getOptionsWithClientId()
|
||||
|
||||
if err = DhcpRelease(c, *l.ack, opts); err != nil {
|
||||
return fmt.Errorf("failed to send DHCPRELEASE")
|
||||
@ -345,7 +441,7 @@ func jitter(span time.Duration) time.Duration {
|
||||
func backoffRetry(resendMax time.Duration, f func() (*dhcp4.Packet, error)) (*dhcp4.Packet, error) {
|
||||
var baseDelay time.Duration = resendDelay0
|
||||
var sleepTime time.Duration
|
||||
|
||||
var fastRetryLimit = resendFastMax
|
||||
for {
|
||||
pkt, err := f()
|
||||
if err == nil {
|
||||
@ -354,15 +450,21 @@ func backoffRetry(resendMax time.Duration, f func() (*dhcp4.Packet, error)) (*dh
|
||||
|
||||
log.Print(err)
|
||||
|
||||
sleepTime = baseDelay + jitter(time.Second)
|
||||
if fastRetryLimit == 0 {
|
||||
sleepTime = baseDelay + jitter(time.Second)
|
||||
} else {
|
||||
sleepTime = resendFastDelay + jitter(time.Second)
|
||||
fastRetryLimit--
|
||||
}
|
||||
|
||||
log.Printf("retrying in %f seconds", sleepTime.Seconds())
|
||||
|
||||
time.Sleep(sleepTime)
|
||||
|
||||
if baseDelay < resendMax {
|
||||
// only adjust delay time if we are in normal backoff stage
|
||||
if baseDelay < resendMax && fastRetryLimit == 0 {
|
||||
baseDelay *= 2
|
||||
} else {
|
||||
} else if fastRetryLimit == 0 { // only break if we are at normal delay
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,43 @@ import (
|
||||
|
||||
const defaultSocketPath = "/run/cni/dhcp.sock"
|
||||
|
||||
// The top-level network config - IPAM plugins are passed the full configuration
|
||||
// of the calling plugin, not just the IPAM section.
|
||||
type NetConf struct {
|
||||
types.NetConf
|
||||
IPAM *IPAMConfig `json:"ipam"`
|
||||
}
|
||||
|
||||
type IPAMConfig struct {
|
||||
types.IPAM
|
||||
DaemonSocketPath string `json:"daemonSocketPath"`
|
||||
// When requesting IP from DHCP server, carry these options for management purpose.
|
||||
// Some fields have default values, and can be override by setting a new option with the same name at here.
|
||||
ProvideOptions []ProvideOption `json:"provide"`
|
||||
// When requesting IP from DHCP server, claiming these options are necessary. Options are necessary unless `optional`
|
||||
// is set to `false`.
|
||||
// To override default requesting fields, set `skipDefault` to `false`.
|
||||
// If an field is not optional, but the server failed to provide it, error will be raised.
|
||||
RequestOptions []RequestOption `json:"request"`
|
||||
}
|
||||
|
||||
// DHCPOption represents a DHCP option. It can be a number, or a string defined in manual dhcp-options(5).
|
||||
// Note that not all DHCP options are supported at all time. Error will be raised if unsupported options are used.
|
||||
type DHCPOption string
|
||||
|
||||
type ProvideOption struct {
|
||||
Option DHCPOption `json:"option"`
|
||||
|
||||
Value string `json:"value"`
|
||||
ValueFromCNIArg string `json:"fromArg"`
|
||||
}
|
||||
|
||||
type RequestOption struct {
|
||||
SkipDefault bool `json:"skipDefault"`
|
||||
|
||||
Option DHCPOption `json:"option"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) > 1 && os.Args[1] == "daemon" {
|
||||
var pidfilePath string
|
||||
@ -55,7 +92,7 @@ func main() {
|
||||
}
|
||||
|
||||
if err := runDaemon(pidfilePath, hostPrefix, socketPath, timeout, resendMax, broadcast); err != nil {
|
||||
log.Printf(err.Error())
|
||||
log.Print(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
@ -88,8 +125,6 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
}
|
||||
|
||||
func cmdCheck(args *skel.CmdArgs) error {
|
||||
// TODO: implement
|
||||
//return fmt.Errorf("not implemented")
|
||||
// Plugin must return result in same version as specified in netconf
|
||||
versionDecoder := &version.ConfigDecoder{}
|
||||
//confVersion, err := versionDecoder.Decode(args.StdinData)
|
||||
@ -106,16 +141,8 @@ func cmdCheck(args *skel.CmdArgs) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type SocketPathConf struct {
|
||||
DaemonSocketPath string `json:"daemonSocketPath,omitempty"`
|
||||
}
|
||||
|
||||
type TempNetConf struct {
|
||||
IPAM SocketPathConf `json:"ipam,omitempty"`
|
||||
}
|
||||
|
||||
func getSocketPath(stdinData []byte) (string, error) {
|
||||
conf := TempNetConf{}
|
||||
conf := NetConf{}
|
||||
if err := json.Unmarshal(stdinData, &conf); err != nil {
|
||||
return "", fmt.Errorf("error parsing socket path conf: %v", err)
|
||||
}
|
||||
|
@ -18,12 +18,33 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/d2g/dhcp4"
|
||||
)
|
||||
|
||||
var optionNameToID = map[string]dhcp4.OptionCode{
|
||||
"dhcp-client-identifier": dhcp4.OptionClientIdentifier,
|
||||
"subnet-mask": dhcp4.OptionSubnetMask,
|
||||
"routers": dhcp4.OptionRouter,
|
||||
"host-name": dhcp4.OptionHostName,
|
||||
"user-class": dhcp4.OptionUserClass,
|
||||
"vendor-class-identifier": dhcp4.OptionVendorClassIdentifier,
|
||||
}
|
||||
|
||||
func parseOptionName(option string) (dhcp4.OptionCode, error) {
|
||||
if val, ok := optionNameToID[option]; ok {
|
||||
return val, nil
|
||||
}
|
||||
i, err := strconv.ParseUint(option, 10, 8)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("Can not parse option: %w", err)
|
||||
}
|
||||
return dhcp4.OptionCode(i), nil
|
||||
}
|
||||
|
||||
func parseRouter(opts dhcp4.Options) net.IP {
|
||||
if opts, ok := opts[dhcp4.OptionRouter]; ok {
|
||||
if len(opts) == 4 {
|
||||
|
@ -16,6 +16,7 @@ package main
|
||||
|
||||
import (
|
||||
"net"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
@ -73,3 +74,34 @@ func TestParseCIDRRoutes(t *testing.T) {
|
||||
|
||||
validateRoutes(t, routes)
|
||||
}
|
||||
|
||||
func TestParseOptionName(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
option string
|
||||
want dhcp4.OptionCode
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
"hostname", "host-name", dhcp4.OptionHostName, false,
|
||||
},
|
||||
{
|
||||
"hostname in number", "12", dhcp4.OptionHostName, false,
|
||||
},
|
||||
{
|
||||
"random string", "doNotparseMe", 0, true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := parseOptionName(tt.option)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("parseOptionName() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("parseOptionName() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
|
||||
|
||||
ip, subnet, err := net.ParseCIDR(ipstr)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("invalid CIDR %s: %s", ipstr, err)
|
||||
return nil, "", fmt.Errorf("the 'ip' field is expected to be in CIDR notation, got: '%s'", ipstr)
|
||||
}
|
||||
|
||||
addr := Address{
|
||||
@ -192,8 +192,13 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
|
||||
if n.Args != nil && n.Args.A != nil && len(n.Args.A.IPs) != 0 {
|
||||
// args IP overwrites IP, so clear IPAM Config
|
||||
n.IPAM.Addresses = make([]Address, 0, len(n.Args.A.IPs))
|
||||
for _, addr := range n.Args.A.IPs {
|
||||
n.IPAM.Addresses = append(n.IPAM.Addresses, Address{AddressStr: addr})
|
||||
for _, addrStr := range n.Args.A.IPs {
|
||||
ip, addr, err := net.ParseCIDR(addrStr)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("an entry in the 'ips' field is NOT in CIDR notation, got: '%s'", addrStr)
|
||||
}
|
||||
addr.IP = ip
|
||||
n.IPAM.Addresses = append(n.IPAM.Addresses, Address{AddressStr: addrStr, Address: *addr})
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,8 +206,13 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
|
||||
if len(n.RuntimeConfig.IPs) != 0 {
|
||||
// runtimeConfig IP overwrites IP, so clear IPAM Config
|
||||
n.IPAM.Addresses = make([]Address, 0, len(n.RuntimeConfig.IPs))
|
||||
for _, addr := range n.RuntimeConfig.IPs {
|
||||
n.IPAM.Addresses = append(n.IPAM.Addresses, Address{AddressStr: addr})
|
||||
for _, addrStr := range n.RuntimeConfig.IPs {
|
||||
ip, addr, err := net.ParseCIDR(addrStr)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("an entry in the 'ips' field is NOT in CIDR notation, got: '%s'", addrStr)
|
||||
}
|
||||
addr.IP = ip
|
||||
n.IPAM.Addresses = append(n.IPAM.Addresses, Address{AddressStr: addrStr, Address: *addr})
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,12 +221,15 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
|
||||
numV6 := 0
|
||||
|
||||
for i := range n.IPAM.Addresses {
|
||||
ip, addr, err := net.ParseCIDR(n.IPAM.Addresses[i].AddressStr)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("invalid CIDR %s: %s", n.IPAM.Addresses[i].AddressStr, err)
|
||||
if n.IPAM.Addresses[i].Address.IP == nil {
|
||||
ip, addr, err := net.ParseCIDR(n.IPAM.Addresses[i].AddressStr)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf(
|
||||
"the 'address' field is expected to be in CIDR notation, got: '%s'", n.IPAM.Addresses[i].AddressStr)
|
||||
}
|
||||
n.IPAM.Addresses[i].Address = *addr
|
||||
n.IPAM.Addresses[i].Address.IP = ip
|
||||
}
|
||||
n.IPAM.Addresses[i].Address = *addr
|
||||
n.IPAM.Addresses[i].Address.IP = ip
|
||||
|
||||
if err := canonicalizeIP(&n.IPAM.Addresses[i].Address.IP); err != nil {
|
||||
return nil, "", fmt.Errorf("invalid address %d: %s", i, err)
|
||||
|
@ -546,6 +546,137 @@ var _ = Describe("static Operations", func() {
|
||||
})
|
||||
Expect(err).Should(MatchError("IPAM config missing 'ipam' key"))
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("[%s] errors when passed an invalid CIDR via ipam config", ver), func() {
|
||||
const ifname string = "eth0"
|
||||
const nspath string = "/some/where"
|
||||
const ipStr string = "10.10.0.1"
|
||||
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "mynet",
|
||||
"type": "bridge",
|
||||
"ipam": {
|
||||
"type": "static",
|
||||
"addresses": [ {
|
||||
"address": "%s"
|
||||
}]
|
||||
}
|
||||
}`, ver, ipStr)
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: nspath,
|
||||
IfName: ifname,
|
||||
StdinData: []byte(conf),
|
||||
}
|
||||
|
||||
// Allocate the IP
|
||||
_, _, err := testutils.CmdAddWithArgs(args, func() error {
|
||||
return cmdAdd(args)
|
||||
})
|
||||
Expect(err).Should(MatchError(
|
||||
fmt.Sprintf("the 'address' field is expected to be in CIDR notation, got: '%s'", ipStr)))
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("[%s] errors when passed an invalid CIDR via Args", ver), func() {
|
||||
const ifname string = "eth0"
|
||||
const nspath string = "/some/where"
|
||||
const ipStr string = "10.10.0.1"
|
||||
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "mynet",
|
||||
"type": "bridge",
|
||||
"ipam": {
|
||||
"type": "static",
|
||||
"routes": [{ "dst": "0.0.0.0/0" }]
|
||||
}
|
||||
}`, ver)
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: nspath,
|
||||
IfName: ifname,
|
||||
StdinData: []byte(conf),
|
||||
Args: fmt.Sprintf("IP=%s", ipStr),
|
||||
}
|
||||
|
||||
// Allocate the IP
|
||||
_, _, err := testutils.CmdAddWithArgs(args, func() error {
|
||||
return cmdAdd(args)
|
||||
})
|
||||
Expect(err).Should(MatchError(
|
||||
fmt.Sprintf("the 'ip' field is expected to be in CIDR notation, got: '%s'", ipStr)))
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("[%s] errors when passed an invalid CIDR via CNI_ARGS", ver), func() {
|
||||
const ifname string = "eth0"
|
||||
const nspath string = "/some/where"
|
||||
const ipStr string = "10.10.0.1"
|
||||
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "mynet",
|
||||
"type": "bridge",
|
||||
"ipam": {
|
||||
"type": "static",
|
||||
"routes": [{ "dst": "0.0.0.0/0" }]
|
||||
},
|
||||
"args": {
|
||||
"cni": {
|
||||
"ips" : ["%s"]
|
||||
}
|
||||
}
|
||||
}`, ver, ipStr)
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: nspath,
|
||||
IfName: ifname,
|
||||
StdinData: []byte(conf),
|
||||
}
|
||||
|
||||
// Allocate the IP
|
||||
_, _, err := testutils.CmdAddWithArgs(args, func() error {
|
||||
return cmdAdd(args)
|
||||
})
|
||||
Expect(err).Should(MatchError(
|
||||
fmt.Sprintf("an entry in the 'ips' field is NOT in CIDR notation, got: '%s'", ipStr)))
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("[%s] errors when passed an invalid CIDR via RuntimeConfig", ver), func() {
|
||||
const ifname string = "eth0"
|
||||
const nspath string = "/some/where"
|
||||
const ipStr string = "10.10.0.1"
|
||||
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "mynet",
|
||||
"type": "bridge",
|
||||
"ipam": {
|
||||
"type": "static",
|
||||
"routes": [{ "dst": "0.0.0.0/0" }]
|
||||
},
|
||||
"RuntimeConfig": {
|
||||
"ips" : ["%s"]
|
||||
}
|
||||
}`, ver, ipStr)
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: nspath,
|
||||
IfName: ifname,
|
||||
StdinData: []byte(conf),
|
||||
}
|
||||
|
||||
// Allocate the IP
|
||||
_, _, err := testutils.CmdAddWithArgs(args, func() error {
|
||||
return cmdAdd(args)
|
||||
})
|
||||
Expect(err).Should(MatchError(
|
||||
fmt.Sprintf("an entry in the 'ips' field is NOT in CIDR notation, got: '%s'", ipStr)))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -18,13 +18,12 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/j-keck/arping"
|
||||
"github.com/vishvananda/netlink"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/skel"
|
||||
@ -33,6 +32,7 @@ import (
|
||||
"github.com/containernetworking/cni/pkg/version"
|
||||
"github.com/containernetworking/plugins/pkg/ip"
|
||||
"github.com/containernetworking/plugins/pkg/ipam"
|
||||
"github.com/containernetworking/plugins/pkg/link"
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/utils"
|
||||
bv "github.com/containernetworking/plugins/pkg/utils/buildversion"
|
||||
@ -55,6 +55,8 @@ type NetConf struct {
|
||||
HairpinMode bool `json:"hairpinMode"`
|
||||
PromiscMode bool `json:"promiscMode"`
|
||||
Vlan int `json:"vlan"`
|
||||
MacSpoofChk bool `json:"macspoofchk,omitempty"`
|
||||
EnableDad bool `json:"enabledad,omitempty"`
|
||||
|
||||
Args struct {
|
||||
Cni BridgeArgs `json:"cni,omitempty"`
|
||||
@ -321,6 +323,11 @@ func ensureVlanInterface(br *netlink.Bridge, vlanId int) (netlink.Link, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to lookup %q: %v", brGatewayIface.Name, err)
|
||||
}
|
||||
|
||||
err = netlink.LinkSetUp(brGatewayVeth)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to up %q: %v", brGatewayIface.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
return brGatewayVeth, nil
|
||||
@ -395,20 +402,6 @@ func setupBridge(n *NetConf) (*netlink.Bridge, *current.Interface, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// disableIPV6DAD disables IPv6 Duplicate Address Detection (DAD)
|
||||
// for an interface, if the interface does not support enhanced_dad.
|
||||
// We do this because interfaces with hairpin mode will see their own DAD packets
|
||||
func disableIPV6DAD(ifName string) error {
|
||||
// ehanced_dad sends a nonce with the DAD packets, so that we can safely
|
||||
// ignore ourselves
|
||||
enh, err := ioutil.ReadFile(fmt.Sprintf("/proc/sys/net/ipv6/conf/%s/enhanced_dad", ifName))
|
||||
if err == nil && string(enh) == "1\n" {
|
||||
return nil
|
||||
}
|
||||
f := fmt.Sprintf("/proc/sys/net/ipv6/conf/%s/accept_dad", ifName)
|
||||
return ioutil.WriteFile(f, []byte("0"), 0644)
|
||||
}
|
||||
|
||||
func enableIPForward(family int) error {
|
||||
if family == netlink.FAMILY_V4 {
|
||||
return ip.EnableIP4Forward()
|
||||
@ -460,6 +453,20 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
},
|
||||
}
|
||||
|
||||
if n.MacSpoofChk {
|
||||
sc := link.NewSpoofChecker(hostInterface.Name, containerInterface.Mac, uniqueID(args.ContainerID, args.IfName))
|
||||
if err := sc.Setup(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if !success {
|
||||
if err := sc.Teardown(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
if isLayer3 {
|
||||
// run the IPAM plugin and get back the config to apply
|
||||
r, err := ipam.ExecAdd(n.IPAM.Type, args.StdinData)
|
||||
@ -495,17 +502,13 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
|
||||
// Configure the container hardware address and IP address(es)
|
||||
if err := netns.Do(func(_ ns.NetNS) error {
|
||||
// Disable IPv6 DAD just in case hairpin mode is enabled on the
|
||||
// bridge. Hairpin mode causes echos of neighbor solicitation
|
||||
// packets, which causes DAD failures.
|
||||
for _, ipc := range result.IPs {
|
||||
if ipc.Address.IP.To4() == nil && (n.HairpinMode || n.PromiscMode) {
|
||||
if err := disableIPV6DAD(args.IfName); err != nil {
|
||||
return err
|
||||
}
|
||||
break
|
||||
}
|
||||
if n.EnableDad {
|
||||
_, _ = sysctl.Sysctl(fmt.Sprintf("/net/ipv6/conf/%s/enhanced_dad", args.IfName), "1")
|
||||
_, _ = sysctl.Sysctl(fmt.Sprintf("net/ipv6/conf/%s/accept_dad", args.IfName), "1")
|
||||
} else {
|
||||
_, _ = sysctl.Sysctl(fmt.Sprintf("net/ipv6/conf/%s/accept_dad", args.IfName), "0")
|
||||
}
|
||||
_, _ = sysctl.Sysctl(fmt.Sprintf("net/ipv4/conf/%s/arp_notify", args.IfName), "1")
|
||||
|
||||
// Add the IP to the interface
|
||||
if err := ipam.ConfigureIface(args.IfName, result); err != nil {
|
||||
@ -534,23 +537,6 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Send a gratuitous arp
|
||||
if err := netns.Do(func(_ ns.NetNS) error {
|
||||
contVeth, err := net.InterfaceByName(args.IfName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, ipc := range result.IPs {
|
||||
if ipc.Address.IP.To4() != nil {
|
||||
_ = arping.GratuitousArpOverIface(ipc.Address.IP, *contVeth)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if n.IsGW {
|
||||
var firstV4Addr net.IP
|
||||
var vlanInterface *current.Interface
|
||||
@ -601,6 +587,20 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err := netns.Do(func(_ ns.NetNS) error {
|
||||
link, err := netlink.LinkByName(args.IfName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve link: %v", err)
|
||||
}
|
||||
// If layer 2 we still need to set the container veth to up
|
||||
if err = netlink.LinkSetUp(link); err != nil {
|
||||
return fmt.Errorf("failed to set %q up: %v", args.IfName, err)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Refetch the bridge since its MAC address may change when the first
|
||||
@ -631,14 +631,17 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
|
||||
isLayer3 := n.IPAM.Type != ""
|
||||
|
||||
if isLayer3 {
|
||||
if err := ipam.ExecDel(n.IPAM.Type, args.StdinData); err != nil {
|
||||
return err
|
||||
ipamDel := func() error {
|
||||
if isLayer3 {
|
||||
if err := ipam.ExecDel(n.IPAM.Type, args.StdinData); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if args.Netns == "" {
|
||||
return nil
|
||||
return ipamDel()
|
||||
}
|
||||
|
||||
// There is a netns so try to clean up. Delete can be called multiple times
|
||||
@ -655,9 +658,28 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// if NetNs is passed down by the Cloud Orchestration Engine, or if it called multiple times
|
||||
// so don't return an error if the device is already removed.
|
||||
// https://github.com/kubernetes/kubernetes/issues/43014#issuecomment-287164444
|
||||
_, ok := err.(ns.NSPathNotExistErr)
|
||||
if ok {
|
||||
return ipamDel()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// call ipam.ExecDel after clean up device in netns
|
||||
if err := ipamDel(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if n.MacSpoofChk {
|
||||
sc := link.NewSpoofChecker("", "", uniqueID(args.ContainerID, args.IfName))
|
||||
if err := sc.Teardown(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if isLayer3 && n.IPMasq {
|
||||
chain := utils.FormatChainName(n.Name, args.ContainerID)
|
||||
comment := utils.FormatComment(n.Name, args.ContainerID)
|
||||
@ -938,3 +960,7 @@ func cmdCheck(args *skel.CmdArgs) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func uniqueID(containerID, cniIface string) string {
|
||||
return containerID + "-" + cniIface
|
||||
}
|
||||
|
@ -23,12 +23,13 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/go-iptables/iptables"
|
||||
"github.com/networkplumbing/go-nft/nft"
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/skel"
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/containernetworking/cni/pkg/types/040"
|
||||
"github.com/containernetworking/cni/pkg/types/100"
|
||||
types040 "github.com/containernetworking/cni/pkg/types/040"
|
||||
types100 "github.com/containernetworking/cni/pkg/types/100"
|
||||
"github.com/containernetworking/plugins/pkg/ip"
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/testutils"
|
||||
@ -65,19 +66,20 @@ type Net struct {
|
||||
// testCase defines the CNI network configuration and the expected
|
||||
// bridge addresses for a test case.
|
||||
type testCase struct {
|
||||
cniVersion string // CNI Version
|
||||
subnet string // Single subnet config: Subnet CIDR
|
||||
gateway string // Single subnet config: Gateway
|
||||
ranges []rangeInfo // Ranges list (multiple subnets config)
|
||||
isGW bool
|
||||
isLayer2 bool
|
||||
expGWCIDRs []string // Expected gateway addresses in CIDR form
|
||||
vlan int
|
||||
ipMasq bool
|
||||
AddErr020 string
|
||||
DelErr020 string
|
||||
AddErr010 string
|
||||
DelErr010 string
|
||||
cniVersion string // CNI Version
|
||||
subnet string // Single subnet config: Subnet CIDR
|
||||
gateway string // Single subnet config: Gateway
|
||||
ranges []rangeInfo // Ranges list (multiple subnets config)
|
||||
isGW bool
|
||||
isLayer2 bool
|
||||
expGWCIDRs []string // Expected gateway addresses in CIDR form
|
||||
vlan int
|
||||
ipMasq bool
|
||||
macspoofchk bool
|
||||
AddErr020 string
|
||||
DelErr020 string
|
||||
AddErr010 string
|
||||
DelErr010 string
|
||||
|
||||
envArgs string // CNI_ARGS
|
||||
runtimeConfig struct {
|
||||
@ -164,6 +166,9 @@ const (
|
||||
ipamEndStr = `
|
||||
}`
|
||||
|
||||
macspoofchkFormat = `,
|
||||
"macspoofchk": %t`
|
||||
|
||||
argsFormat = `,
|
||||
"args": {
|
||||
"cni": {
|
||||
@ -193,6 +198,9 @@ func (tc testCase) netConfJSON(dataDir string) string {
|
||||
if tc.runtimeConfig.mac != "" {
|
||||
conf += fmt.Sprintf(runtimeConfig, tc.runtimeConfig.mac)
|
||||
}
|
||||
if tc.macspoofchk {
|
||||
conf += fmt.Sprintf(macspoofchkFormat, tc.macspoofchk)
|
||||
}
|
||||
|
||||
if !tc.isLayer2 {
|
||||
conf += netDefault
|
||||
@ -2175,6 +2183,35 @@ var _ = Describe("bridge Operations", func() {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
It(fmt.Sprintf("[%s] configures mac spoof-check (no mac spoofing)", ver), func() {
|
||||
Expect(originalNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
tc := testCase{
|
||||
cniVersion: ver,
|
||||
subnet: "10.1.2.0/24",
|
||||
macspoofchk: true,
|
||||
}
|
||||
args := tc.createCmdArgs(originalNS, dataDir)
|
||||
_, _, err := testutils.CmdAddWithArgs(args, func() error {
|
||||
return cmdAdd(args)
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
assertMacSpoofCheckRulesExist()
|
||||
|
||||
Expect(testutils.CmdDelWithArgs(args, func() error {
|
||||
if err := cmdDel(args); err != nil {
|
||||
return err
|
||||
}
|
||||
assertMacSpoofCheckRulesMissing()
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
})
|
||||
}
|
||||
|
||||
It("check vlan id when loading net conf", func() {
|
||||
@ -2211,3 +2248,50 @@ var _ = Describe("bridge Operations", func() {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
func assertMacSpoofCheckRulesExist() {
|
||||
assertMacSpoofCheckRules(
|
||||
func(actual interface{}, expectedLen int) {
|
||||
ExpectWithOffset(3, actual).To(HaveLen(expectedLen))
|
||||
})
|
||||
}
|
||||
|
||||
func assertMacSpoofCheckRulesMissing() {
|
||||
assertMacSpoofCheckRules(
|
||||
func(actual interface{}, _ int) {
|
||||
ExpectWithOffset(3, actual).To(BeEmpty())
|
||||
})
|
||||
}
|
||||
|
||||
func assertMacSpoofCheckRules(assert func(actual interface{}, expectedLen int)) {
|
||||
c, err := nft.ReadConfig()
|
||||
ExpectWithOffset(2, err).NotTo(HaveOccurred())
|
||||
|
||||
expectedTable := nft.NewTable("nat", "bridge")
|
||||
filter := nft.TypeFilter
|
||||
hook := nft.HookPreRouting
|
||||
prio := -300
|
||||
policy := nft.PolicyAccept
|
||||
expectedBaseChain := nft.NewChain(expectedTable, "PREROUTING", &filter, &hook, &prio, &policy)
|
||||
|
||||
assert(c.LookupRule(nft.NewRule(
|
||||
expectedTable,
|
||||
expectedBaseChain,
|
||||
nil, nil, nil,
|
||||
"macspoofchk-dummy-0-eth0",
|
||||
)), 1)
|
||||
|
||||
assert(c.LookupRule(nft.NewRule(
|
||||
expectedTable,
|
||||
nft.NewRegularChain(expectedTable, "cni-br-iface-dummy-0-eth0"),
|
||||
nil, nil, nil,
|
||||
"macspoofchk-dummy-0-eth0",
|
||||
)), 1)
|
||||
|
||||
assert(c.LookupRule(nft.NewRule(
|
||||
expectedTable,
|
||||
nft.NewRegularChain(expectedTable, "cni-br-iface-dummy-0-eth0-mac"),
|
||||
nil, nil, nil,
|
||||
"macspoofchk-dummy-0-eth0",
|
||||
)), 2)
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ import (
|
||||
bv "github.com/containernetworking/plugins/pkg/utils/buildversion"
|
||||
)
|
||||
|
||||
const (
|
||||
var (
|
||||
sysBusPCI = "/sys/bus/pci/devices"
|
||||
)
|
||||
|
||||
@ -49,8 +49,9 @@ var userspaceDrivers = []string{"vfio-pci", "uio_pci_generic", "igb_uio"}
|
||||
//NetConf for host-device config, look the README to learn how to use those parameters
|
||||
type NetConf struct {
|
||||
types.NetConf
|
||||
Device string `json:"device"` // Device-Name, something like eth0 or can0 etc.
|
||||
HWAddr string `json:"hwaddr"` // MAC Address of target network interface
|
||||
Device string `json:"device"` // Device-Name, something like eth0 or can0 etc.
|
||||
HWAddr string `json:"hwaddr"` // MAC Address of target network interface
|
||||
DPDKMode bool
|
||||
KernelPath string `json:"kernelpath"` // Kernelpath of the device
|
||||
PCIAddr string `json:"pciBusID"` // PCI Address of target network device
|
||||
RuntimeConfig struct {
|
||||
@ -67,7 +68,8 @@ func init() {
|
||||
|
||||
func loadConf(bytes []byte) (*NetConf, error) {
|
||||
n := &NetConf{}
|
||||
if err := json.Unmarshal(bytes, n); err != nil {
|
||||
var err error
|
||||
if err = json.Unmarshal(bytes, n); err != nil {
|
||||
return nil, fmt.Errorf("failed to load netconf: %v", err)
|
||||
}
|
||||
|
||||
@ -80,6 +82,13 @@ func loadConf(bytes []byte) (*NetConf, error) {
|
||||
return nil, fmt.Errorf(`specify either "device", "hwaddr", "kernelpath" or "pciBusID"`)
|
||||
}
|
||||
|
||||
if len(n.PCIAddr) > 0 {
|
||||
n.DPDKMode, err = hasDpdkDriver(n.PCIAddr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error with host device: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
@ -94,49 +103,17 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
}
|
||||
defer containerNs.Close()
|
||||
|
||||
if len(cfg.PCIAddr) > 0 {
|
||||
isDpdkMode, err := hasDpdkDriver(cfg.PCIAddr)
|
||||
result := ¤t.Result{}
|
||||
var contDev netlink.Link
|
||||
if !cfg.DPDKMode {
|
||||
hostDev, err := getLink(cfg.Device, cfg.HWAddr, cfg.KernelPath, cfg.PCIAddr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error with host device: %v", err)
|
||||
return fmt.Errorf("failed to find host device: %v", err)
|
||||
}
|
||||
if isDpdkMode {
|
||||
return types.PrintResult(¤t.Result{}, cfg.CNIVersion)
|
||||
}
|
||||
}
|
||||
|
||||
hostDev, err := getLink(cfg.Device, cfg.HWAddr, cfg.KernelPath, cfg.PCIAddr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find host device: %v", err)
|
||||
}
|
||||
|
||||
contDev, err := moveLinkIn(hostDev, containerNs, args.IfName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to move link %v", err)
|
||||
}
|
||||
|
||||
var result *current.Result
|
||||
// run the IPAM plugin and get back the config to apply
|
||||
if cfg.IPAM.Type != "" {
|
||||
r, err := ipam.ExecAdd(cfg.IPAM.Type, args.StdinData)
|
||||
contDev, err = moveLinkIn(hostDev, containerNs, args.IfName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Invoke ipam del if err to avoid ip leak
|
||||
defer func() {
|
||||
if err != nil {
|
||||
ipam.ExecDel(cfg.IPAM.Type, args.StdinData)
|
||||
}
|
||||
}()
|
||||
|
||||
// Convert whatever the IPAM result was into the current Result type
|
||||
result, err = current.NewResultFromResult(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(result.IPs) == 0 {
|
||||
return errors.New("IPAM plugin returned missing IP config")
|
||||
return fmt.Errorf("failed to move link %v", err)
|
||||
}
|
||||
|
||||
result.Interfaces = []*current.Interface{{
|
||||
@ -144,13 +121,48 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
Mac: contDev.Attrs().HardwareAddr.String(),
|
||||
Sandbox: containerNs.Path(),
|
||||
}}
|
||||
for _, ipc := range result.IPs {
|
||||
// All addresses apply to the container interface (move from host)
|
||||
ipc.Interface = current.Int(0)
|
||||
}
|
||||
}
|
||||
|
||||
if cfg.IPAM.Type == "" {
|
||||
if cfg.DPDKMode {
|
||||
return types.PrintResult(result, cfg.CNIVersion)
|
||||
}
|
||||
return printLink(contDev, cfg.CNIVersion, containerNs)
|
||||
}
|
||||
|
||||
// run the IPAM plugin and get back the config to apply
|
||||
r, err := ipam.ExecAdd(cfg.IPAM.Type, args.StdinData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Invoke ipam del if err to avoid ip leak
|
||||
defer func() {
|
||||
if err != nil {
|
||||
ipam.ExecDel(cfg.IPAM.Type, args.StdinData)
|
||||
}
|
||||
}()
|
||||
|
||||
// Convert whatever the IPAM result was into the current Result type
|
||||
newResult, err := current.NewResultFromResult(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(newResult.IPs) == 0 {
|
||||
return errors.New("IPAM plugin returned missing IP config")
|
||||
}
|
||||
|
||||
for _, ipc := range newResult.IPs {
|
||||
// All addresses apply to the container interface (move from host)
|
||||
ipc.Interface = current.Int(0)
|
||||
}
|
||||
|
||||
newResult.Interfaces = result.Interfaces
|
||||
|
||||
if !cfg.DPDKMode {
|
||||
err = containerNs.Do(func(_ ns.NetNS) error {
|
||||
if err := ipam.ConfigureIface(args.IfName, result); err != nil {
|
||||
if err := ipam.ConfigureIface(args.IfName, newResult); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -158,13 +170,11 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result.DNS = cfg.DNS
|
||||
|
||||
return types.PrintResult(result, cfg.CNIVersion)
|
||||
}
|
||||
|
||||
return printLink(contDev, cfg.CNIVersion, containerNs)
|
||||
newResult.DNS = cfg.DNS
|
||||
|
||||
return types.PrintResult(newResult, cfg.CNIVersion)
|
||||
}
|
||||
|
||||
func cmdDel(args *skel.CmdArgs) error {
|
||||
@ -181,26 +191,18 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
}
|
||||
defer containerNs.Close()
|
||||
|
||||
if len(cfg.PCIAddr) > 0 {
|
||||
isDpdkMode, err := hasDpdkDriver(cfg.PCIAddr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error with host device: %v", err)
|
||||
}
|
||||
if isDpdkMode {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if err := moveLinkOut(containerNs, args.IfName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cfg.IPAM.Type != "" {
|
||||
if err := ipam.ExecDel(cfg.IPAM.Type, args.StdinData); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if !cfg.DPDKMode {
|
||||
if err := moveLinkOut(containerNs, args.IfName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -228,6 +230,10 @@ func moveLinkIn(hostDev netlink.Link, containerNs ns.NetNS, ifName string) (netl
|
||||
if err := netlink.LinkSetName(contDev, ifName); err != nil {
|
||||
return fmt.Errorf("failed to rename device %q to %q: %v", hostDev.Attrs().Name, ifName, err)
|
||||
}
|
||||
// Bring container device up
|
||||
if err = netlink.LinkSetUp(contDev); err != nil {
|
||||
return fmt.Errorf("failed to set %q up: %v", ifName, err)
|
||||
}
|
||||
// Retrieve link again to get up-to-date name and attributes
|
||||
contDev, err = netlink.LinkByName(ifName)
|
||||
if err != nil {
|
||||
@ -259,17 +265,21 @@ func moveLinkOut(containerNs ns.NetNS, ifName string) error {
|
||||
return fmt.Errorf("failed to set %q down: %v", ifName, err)
|
||||
}
|
||||
|
||||
// Rename device to it's original name
|
||||
defer func() {
|
||||
// If moving the device to the host namespace fails, set its name back to ifName so that this
|
||||
// function can be retried. Also bring the device back up, unless it was already down before.
|
||||
if err != nil {
|
||||
_ = netlink.LinkSetName(dev, ifName)
|
||||
if dev.Attrs().Flags&net.FlagUp == net.FlagUp {
|
||||
_ = netlink.LinkSetUp(dev)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Rename the device to its original name from the host namespace
|
||||
if err = netlink.LinkSetName(dev, dev.Attrs().Alias); err != nil {
|
||||
return fmt.Errorf("failed to restore %q to original name %q: %v", ifName, dev.Attrs().Alias, err)
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
// if moving device to host namespace fails, we should revert device name
|
||||
// to ifName to make sure that device can be found in retries
|
||||
_ = netlink.LinkSetName(dev, ifName)
|
||||
}
|
||||
}()
|
||||
|
||||
if err = netlink.LinkSetNsFd(dev, int(defaultNs.Fd())); err != nil {
|
||||
return fmt.Errorf("failed to move %q to host netns: %v", dev.Attrs().Alias, err)
|
||||
@ -410,6 +420,10 @@ func cmdCheck(args *skel.CmdArgs) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if cfg.DPDKMode {
|
||||
return nil
|
||||
}
|
||||
|
||||
var contMap current.Interface
|
||||
// Find interfaces for name we know, that of host-device inside container
|
||||
for _, intf := range result.Interfaces {
|
||||
|
@ -17,14 +17,17 @@ package main
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/skel"
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/containernetworking/cni/pkg/types/040"
|
||||
"github.com/containernetworking/cni/pkg/types/100"
|
||||
types040 "github.com/containernetworking/cni/pkg/types/040"
|
||||
types100 "github.com/containernetworking/cni/pkg/types/100"
|
||||
"github.com/containernetworking/cni/pkg/version"
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/testutils"
|
||||
@ -217,6 +220,7 @@ func buildOneConfig(name, cniVersion string, orig *Net, prevResult types.Result)
|
||||
|
||||
type tester interface {
|
||||
expectInterfaces(result types.Result, name, mac, sandbox string)
|
||||
expectDpdkInterfaceIP(result types.Result, ipAddress string)
|
||||
}
|
||||
|
||||
type testerBase struct{}
|
||||
@ -252,6 +256,15 @@ func (t *testerV10x) expectInterfaces(result types.Result, name, mac, sandbox st
|
||||
}))
|
||||
}
|
||||
|
||||
func (t *testerV10x) expectDpdkInterfaceIP(result types.Result, ipAddress string) {
|
||||
// check that the result was sane
|
||||
res, err := types100.NewResultFromResult(result)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(res.Interfaces)).To(Equal(0))
|
||||
Expect(len(res.IPs)).To(Equal(1))
|
||||
Expect(res.IPs[0].Address.String()).To(Equal(ipAddress))
|
||||
}
|
||||
|
||||
func (t *testerV04x) expectInterfaces(result types.Result, name, mac, sandbox string) {
|
||||
// check that the result was sane
|
||||
res, err := types040.NewResultFromResult(result)
|
||||
@ -265,6 +278,15 @@ func (t *testerV04x) expectInterfaces(result types.Result, name, mac, sandbox st
|
||||
}))
|
||||
}
|
||||
|
||||
func (t *testerV04x) expectDpdkInterfaceIP(result types.Result, ipAddress string) {
|
||||
// check that the result was sane
|
||||
res, err := types040.NewResultFromResult(result)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(res.Interfaces)).To(Equal(0))
|
||||
Expect(len(res.IPs)).To(Equal(1))
|
||||
Expect(res.IPs[0].Address.String()).To(Equal(ipAddress))
|
||||
}
|
||||
|
||||
func (t *testerV03x) expectInterfaces(result types.Result, name, mac, sandbox string) {
|
||||
// check that the result was sane
|
||||
res, err := types040.NewResultFromResult(result)
|
||||
@ -278,6 +300,15 @@ func (t *testerV03x) expectInterfaces(result types.Result, name, mac, sandbox st
|
||||
}))
|
||||
}
|
||||
|
||||
func (t *testerV03x) expectDpdkInterfaceIP(result types.Result, ipAddress string) {
|
||||
// check that the result was sane
|
||||
res, err := types040.NewResultFromResult(result)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(len(res.Interfaces)).To(Equal(0))
|
||||
Expect(len(res.IPs)).To(Equal(1))
|
||||
Expect(res.IPs[0].Address.String()).To(Equal(ipAddress))
|
||||
}
|
||||
|
||||
var _ = Describe("base functionality", func() {
|
||||
var originalNS, targetNS ns.NetNS
|
||||
var ifname string
|
||||
@ -350,12 +381,13 @@ var _ = Describe("base functionality", func() {
|
||||
t := newTesterByVersion(ver)
|
||||
t.expectInterfaces(resI, cniName, origLink.Attrs().HardwareAddr.String(), targetNS.Path())
|
||||
|
||||
// assert that dummy0 is now in the target namespace
|
||||
// assert that dummy0 is now in the target namespace and is up
|
||||
_ = targetNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
link, err := netlink.LinkByName(cniName)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
|
||||
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
|
||||
return nil
|
||||
})
|
||||
|
||||
@ -430,12 +462,13 @@ var _ = Describe("base functionality", func() {
|
||||
t := newTesterByVersion(ver)
|
||||
t.expectInterfaces(resI, cniName, origLink.Attrs().HardwareAddr.String(), targetNS.Path())
|
||||
|
||||
// assert that dummy0 is now in the target namespace
|
||||
// assert that dummy0 is now in the target namespace and is up
|
||||
_ = targetNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
link, err := netlink.LinkByName(cniName)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
|
||||
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
|
||||
return nil
|
||||
})
|
||||
|
||||
@ -473,12 +506,13 @@ var _ = Describe("base functionality", func() {
|
||||
return nil
|
||||
})
|
||||
|
||||
// assert container interface "eth0" still exists in target namespace
|
||||
// assert container interface "eth0" still exists in target namespace and is up
|
||||
_ = targetNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
link, err := netlink.LinkByName(cniName)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
|
||||
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
|
||||
return nil
|
||||
})
|
||||
|
||||
@ -509,6 +543,65 @@ var _ = Describe("base functionality", func() {
|
||||
})
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("Works with a valid %s config on a DPDK device with IPAM", ver), func() {
|
||||
fs := &fakeFilesystem{
|
||||
dirs: []string{
|
||||
"sys/bus/pci/devices/0000:00:00.1",
|
||||
"sys/bus/pci/drivers/vfio-pci",
|
||||
},
|
||||
symlinks: map[string]string{
|
||||
"sys/bus/pci/devices/0000:00:00.1/driver": "../../../../bus/pci/drivers/vfio-pci",
|
||||
},
|
||||
}
|
||||
defer fs.use()()
|
||||
|
||||
// call CmdAdd
|
||||
targetIP := "10.10.0.1/24"
|
||||
cniName := "eth0"
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-host-device-test",
|
||||
"type": "host-device",
|
||||
"ipam": {
|
||||
"type": "static",
|
||||
"addresses": [
|
||||
{
|
||||
"address":"`+targetIP+`",
|
||||
"gateway": "10.10.0.254"
|
||||
}]
|
||||
},
|
||||
"pciBusID": %q
|
||||
}`, ver, "0000:00:00.1")
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
IfName: cniName,
|
||||
Netns: targetNS.Path(),
|
||||
StdinData: []byte(conf),
|
||||
}
|
||||
var resI types.Result
|
||||
err := originalNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
var err error
|
||||
resI, _, err = testutils.CmdAddWithArgs(args, func() error { return cmdAdd(args) })
|
||||
return err
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// check that the result was sane
|
||||
t := newTesterByVersion(ver)
|
||||
t.expectDpdkInterfaceIP(resI, targetIP)
|
||||
|
||||
// call CmdDel
|
||||
_ = originalNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
err = testutils.CmdDelWithArgs(args, func() error {
|
||||
return cmdDel(args)
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
return nil
|
||||
})
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("Works with a valid %s config with IPAM", ver), func() {
|
||||
var origLink netlink.Link
|
||||
|
||||
@ -564,12 +657,13 @@ var _ = Describe("base functionality", func() {
|
||||
t := newTesterByVersion(ver)
|
||||
t.expectInterfaces(resI, cniName, origLink.Attrs().HardwareAddr.String(), targetNS.Path())
|
||||
|
||||
// assert that dummy0 is now in the target namespace
|
||||
// assert that dummy0 is now in the target namespace and is up
|
||||
_ = targetNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
link, err := netlink.LinkByName(cniName)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
|
||||
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
|
||||
|
||||
//get the IP address of the interface in the target namespace
|
||||
addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
|
||||
@ -667,12 +761,13 @@ var _ = Describe("base functionality", func() {
|
||||
t := newTesterByVersion(ver)
|
||||
t.expectInterfaces(resI, cniName, origLink.Attrs().HardwareAddr.String(), targetNS.Path())
|
||||
|
||||
// assert that dummy0 is now in the target namespace
|
||||
// assert that dummy0 is now in the target namespace and is up
|
||||
_ = targetNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
link, err := netlink.LinkByName(cniName)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
|
||||
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
|
||||
return nil
|
||||
})
|
||||
|
||||
@ -721,6 +816,89 @@ var _ = Describe("base functionality", func() {
|
||||
})
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("Works with a valid %s config on a DPDK device with IPAM", ver), func() {
|
||||
fs := &fakeFilesystem{
|
||||
dirs: []string{
|
||||
"sys/bus/pci/devices/0000:00:00.1",
|
||||
"sys/bus/pci/drivers/vfio-pci",
|
||||
},
|
||||
symlinks: map[string]string{
|
||||
"sys/bus/pci/devices/0000:00:00.1/driver": "../../../../bus/pci/drivers/vfio-pci",
|
||||
},
|
||||
}
|
||||
defer fs.use()()
|
||||
|
||||
// call CmdAdd
|
||||
targetIP := "10.10.0.1/24"
|
||||
cniName := "eth0"
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-host-device-test",
|
||||
"type": "host-device",
|
||||
"ipam": {
|
||||
"type": "static",
|
||||
"addresses": [
|
||||
{
|
||||
"address":"`+targetIP+`",
|
||||
"gateway": "10.10.0.254"
|
||||
}]
|
||||
},
|
||||
"pciBusID": %q
|
||||
}`, ver, "0000:00:00.1")
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: targetNS.Path(),
|
||||
IfName: cniName,
|
||||
StdinData: []byte(conf),
|
||||
}
|
||||
var resI types.Result
|
||||
err := originalNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
var err error
|
||||
resI, _, err = testutils.CmdAddWithArgs(args, func() error { return cmdAdd(args) })
|
||||
return err
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// check that the result was sane
|
||||
t := newTesterByVersion(ver)
|
||||
t.expectDpdkInterfaceIP(resI, targetIP)
|
||||
|
||||
// call CmdCheck
|
||||
n := &Net{}
|
||||
err = json.Unmarshal([]byte(conf), &n)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
n.IPAM, _, err = LoadIPAMConfig([]byte(conf), "")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
if testutils.SpecVersionHasCHECK(ver) {
|
||||
newConf, err := buildOneConfig("testConfig", ver, n, resI)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
confString, err := json.Marshal(newConf)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
args.StdinData = confString
|
||||
|
||||
err = originalNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
return testutils.CmdCheckWithArgs(args, func() error { return cmdCheck(args) })
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
// call CmdDel
|
||||
_ = originalNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
err = testutils.CmdDelWithArgs(args, func() error {
|
||||
return cmdDel(args)
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
return nil
|
||||
})
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("Works with a valid %s config with IPAM", ver), func() {
|
||||
var origLink netlink.Link
|
||||
|
||||
@ -776,12 +954,13 @@ var _ = Describe("base functionality", func() {
|
||||
t := newTesterByVersion(ver)
|
||||
t.expectInterfaces(resI, cniName, origLink.Attrs().HardwareAddr.String(), targetNS.Path())
|
||||
|
||||
// assert that dummy0 is now in the target namespace
|
||||
// assert that dummy0 is now in the target namespace and is up
|
||||
_ = targetNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
link, err := netlink.LinkByName(cniName)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
|
||||
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
|
||||
|
||||
//get the IP address of the interface in the target namespace
|
||||
addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
|
||||
@ -890,12 +1069,13 @@ var _ = Describe("base functionality", func() {
|
||||
t := newTesterByVersion(ver)
|
||||
t.expectInterfaces(resI, cniName, origLink.Attrs().HardwareAddr.String(), targetNS.Path())
|
||||
|
||||
// assert that dummy0 is now in the target namespace
|
||||
// assert that dummy0 is now in the target namespace and is up
|
||||
_ = targetNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
link, err := netlink.LinkByName(cniName)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
|
||||
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
|
||||
return nil
|
||||
})
|
||||
|
||||
@ -933,12 +1113,13 @@ var _ = Describe("base functionality", func() {
|
||||
return nil
|
||||
})
|
||||
|
||||
// assert container interface "eth0" still exists in target namespace
|
||||
// assert container interface "eth0" still exists in target namespace and is up
|
||||
err = targetNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
link, err := netlink.LinkByName(cniName)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
|
||||
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
|
||||
return nil
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
@ -971,3 +1152,42 @@ var _ = Describe("base functionality", func() {
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
type fakeFilesystem struct {
|
||||
rootDir string
|
||||
dirs []string
|
||||
symlinks map[string]string
|
||||
}
|
||||
|
||||
func (fs *fakeFilesystem) use() func() {
|
||||
// create the new fake fs root dir in /tmp/sriov...
|
||||
tmpDir, err := ioutil.TempDir("", "sriov")
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("error creating fake root dir: %s", err.Error()))
|
||||
}
|
||||
fs.rootDir = tmpDir
|
||||
|
||||
for _, dir := range fs.dirs {
|
||||
err := os.MkdirAll(path.Join(fs.rootDir, dir), 0755)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("error creating fake directory: %s", err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
for link, target := range fs.symlinks {
|
||||
err = os.Symlink(target, path.Join(fs.rootDir, link))
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("error creating fake symlink: %s", err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
sysBusPCI = path.Join(fs.rootDir, "/sys/bus/pci/devices")
|
||||
|
||||
return func() {
|
||||
// remove temporary fake fs
|
||||
err := os.RemoveAll(fs.rootDir)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("error tearing down fake filesystem: %s", err.Error()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ import (
|
||||
"github.com/containernetworking/plugins/pkg/ipam"
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
bv "github.com/containernetworking/plugins/pkg/utils/buildversion"
|
||||
"github.com/containernetworking/plugins/pkg/utils/sysctl"
|
||||
)
|
||||
|
||||
type NetConf struct {
|
||||
@ -254,7 +255,12 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
result.Interfaces = []*current.Interface{ipvlanInterface}
|
||||
|
||||
err = netns.Do(func(_ ns.NetNS) error {
|
||||
return ipam.ConfigureIface(args.IfName, result)
|
||||
_, _ = sysctl.Sysctl(fmt.Sprintf("net/ipv4/conf/%s/arp_notify", args.IfName), "1")
|
||||
|
||||
if err := ipam.ConfigureIface(args.IfName, result); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@ -294,6 +300,17 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// if NetNs is passed down by the Cloud Orchestration Engine, or if it called multiple times
|
||||
// so don't return an error if the device is already removed.
|
||||
// https://github.com/kubernetes/kubernetes/issues/43014#issuecomment-287164444
|
||||
_, ok := err.(ns.NSPathNotExistErr)
|
||||
if ok {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -159,7 +159,14 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err // not tested
|
||||
// if NetNs is passed down by the Cloud Orchestration Engine, or if it called multiple times
|
||||
// so don't return an error if the device is already removed.
|
||||
// https://github.com/kubernetes/kubernetes/issues/43014#issuecomment-287164444
|
||||
_, ok := err.(ns.NSPathNotExistErr)
|
||||
if ok {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -21,7 +21,6 @@ import (
|
||||
"net"
|
||||
"runtime"
|
||||
|
||||
"github.com/j-keck/arping"
|
||||
"github.com/vishvananda/netlink"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/skel"
|
||||
@ -33,6 +32,7 @@ import (
|
||||
"github.com/containernetworking/plugins/pkg/ipam"
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
bv "github.com/containernetworking/plugins/pkg/utils/buildversion"
|
||||
"github.com/containernetworking/plugins/pkg/utils/sysctl"
|
||||
)
|
||||
|
||||
type NetConf struct {
|
||||
@ -294,20 +294,11 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
}
|
||||
|
||||
err = netns.Do(func(_ ns.NetNS) error {
|
||||
_, _ = sysctl.Sysctl(fmt.Sprintf("net/ipv4/conf/%s/arp_notify", args.IfName), "1")
|
||||
|
||||
if err := ipam.ConfigureIface(args.IfName, result); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
contVeth, err := net.InterfaceByName(args.IfName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to look up %q: %v", args.IfName, err)
|
||||
}
|
||||
|
||||
for _, ipc := range result.IPs {
|
||||
if ipc.Address.IP.To4() != nil {
|
||||
_ = arping.GratuitousArpOverIface(ipc.Address.IP, *contVeth)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@ -367,6 +358,17 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// if NetNs is passed down by the Cloud Orchestration Engine, or if it called multiple times
|
||||
// so don't return an error if the device is already removed.
|
||||
// https://github.com/kubernetes/kubernetes/issues/43014#issuecomment-287164444
|
||||
_, ok := err.(ns.NSPathNotExistErr)
|
||||
if ok {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,6 @@ import (
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/j-keck/arping"
|
||||
"github.com/vishvananda/netlink"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/skel"
|
||||
@ -83,15 +82,15 @@ func setupContainerVeth(netns ns.NetNS, ifName string, mtu int, pr *current.Resu
|
||||
|
||||
pr.Interfaces = []*current.Interface{hostInterface, containerInterface}
|
||||
|
||||
if err = ipam.ConfigureIface(ifName, pr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
contVeth, err := net.InterfaceByName(ifName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to look up %q: %v", ifName, err)
|
||||
}
|
||||
|
||||
if err = ipam.ConfigureIface(ifName, pr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, ipc := range pr.IPs {
|
||||
// Delete the route that was automatically added
|
||||
route := netlink.Route{
|
||||
@ -139,13 +138,6 @@ func setupContainerVeth(netns ns.NetNS, ifName string, mtu int, pr *current.Resu
|
||||
}
|
||||
}
|
||||
|
||||
// Send a gratuitous arp for all v4 addresses
|
||||
for _, ipc := range pr.IPs {
|
||||
if ipc.Address.IP.To4() != nil {
|
||||
_ = arping.GratuitousArpOverIface(ipc.Address.IP, *contVeth)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@ -292,6 +284,13 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// if NetNs is passed down by the Cloud Orchestration Engine, or if it called multiple times
|
||||
// so don't return an error if the device is already removed.
|
||||
// https://github.com/kubernetes/kubernetes/issues/43014#issuecomment-287164444
|
||||
_, ok := err.(ns.NSPathNotExistErr)
|
||||
if ok {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -213,6 +213,17 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
return err
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// if NetNs is passed down by the Cloud Orchestration Engine, or if it called multiple times
|
||||
// so don't return an error if the device is already removed.
|
||||
// https://github.com/kubernetes/kubernetes/issues/43014#issuecomment-287164444
|
||||
_, ok := err.(ns.NSPathNotExistErr)
|
||||
if ok {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -46,8 +46,27 @@ type FirewallNetConf struct {
|
||||
// the firewalld backend is used but the zone is not given, it defaults
|
||||
// to 'trusted'
|
||||
FirewalldZone string `json:"firewalldZone,omitempty"`
|
||||
|
||||
// IngressPolicy is an optional ingress policy.
|
||||
// Defaults to "open".
|
||||
IngressPolicy IngressPolicy `json:"ingressPolicy,omitempty"`
|
||||
}
|
||||
|
||||
// IngressPolicy is an ingress policy string.
|
||||
type IngressPolicy = string
|
||||
|
||||
const (
|
||||
// IngressPolicyOpen ("open"): all inbound connections to the container are accepted.
|
||||
// IngressPolicyOpen is the default ingress policy.
|
||||
IngressPolicyOpen IngressPolicy = "open"
|
||||
|
||||
// IngressPolicySameBridge ("same-bridge"): connections from the same bridge are accepted, others are blocked.
|
||||
// This is similar to how Docker libnetwork works.
|
||||
// IngressPolicySameBridge executes `iptables` regardless to the value of `Backend`.
|
||||
// IngressPolicySameBridge may not work as expected for non-bridge networks.
|
||||
IngressPolicySameBridge IngressPolicy = "same-bridge"
|
||||
)
|
||||
|
||||
type FirewallBackend interface {
|
||||
Add(*FirewallNetConf, *current.Result) error
|
||||
Del(*FirewallNetConf, *current.Result) error
|
||||
@ -129,6 +148,10 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := setupIngressPolicy(conf, result); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if result == nil {
|
||||
result = ¤t.Result{
|
||||
CNIVersion: current.ImplementedSpecVersion,
|
||||
@ -153,6 +176,10 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := teardownIngressPolicy(conf, result); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
203
plugins/meta/firewall/firewall_integ_test.go
Normal file
203
plugins/meta/firewall/firewall_integ_test.go
Normal file
@ -0,0 +1,203 @@
|
||||
// Copyright 2022 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 main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/containernetworking/cni/libcni"
|
||||
types100 "github.com/containernetworking/cni/pkg/types/100"
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/testutils"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
// The integration tests expect the "firewall" binary to be present in $PATH.
|
||||
// To run test, e.g, : go test -exec "sudo -E PATH=$(pwd):/opt/cni/bin:$PATH" -v -ginkgo.v
|
||||
var _ = Describe("firewall integration tests (ingressPolicy: same-bridge)", func() {
|
||||
// ns0: foo (10.88.3.0/24)
|
||||
// ns1: foo (10.88.3.0/24)
|
||||
// ns2: bar (10.88.4.0/24)
|
||||
//
|
||||
// ns0@foo can talk to ns1@foo, but cannot talk to ns2@bar
|
||||
const nsCount = 3
|
||||
var (
|
||||
configListFoo *libcni.NetworkConfigList // "foo", 10.88.3.0/24
|
||||
configListBar *libcni.NetworkConfigList // "bar", 10.88.4.0/24
|
||||
cniConf *libcni.CNIConfig
|
||||
namespaces [nsCount]ns.NetNS
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
rawConfigFoo := `
|
||||
{
|
||||
"cniVersion": "1.0.0",
|
||||
"name": "foo",
|
||||
"plugins": [
|
||||
{
|
||||
"type": "bridge",
|
||||
"bridge": "foo",
|
||||
"isGateway": true,
|
||||
"ipMasq": true,
|
||||
"hairpinMode": true,
|
||||
"ipam": {
|
||||
"type": "host-local",
|
||||
"routes": [
|
||||
{
|
||||
"dst": "0.0.0.0/0"
|
||||
}
|
||||
],
|
||||
"ranges": [
|
||||
[
|
||||
{
|
||||
"subnet": "10.88.3.0/24",
|
||||
"gateway": "10.88.3.1"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "firewall",
|
||||
"backend": "iptables",
|
||||
"ingressPolicy": "same-bridge"
|
||||
}
|
||||
]
|
||||
}
|
||||
`
|
||||
configListFoo, err = libcni.ConfListFromBytes([]byte(rawConfigFoo))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
rawConfigBar := strings.ReplaceAll(rawConfigFoo, "foo", "bar")
|
||||
rawConfigBar = strings.ReplaceAll(rawConfigBar, "10.88.3.", "10.88.4.")
|
||||
|
||||
configListBar, err = libcni.ConfListFromBytes([]byte(rawConfigBar))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// turn PATH in to CNI_PATH.
|
||||
_, err = exec.LookPath("firewall")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
dirs := filepath.SplitList(os.Getenv("PATH"))
|
||||
cniConf = &libcni.CNIConfig{Path: dirs}
|
||||
|
||||
for i := 0; i < nsCount; i++ {
|
||||
targetNS, err := testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
fmt.Fprintf(GinkgoWriter, "namespace %d:%s\n", i, targetNS.Path())
|
||||
namespaces[i] = targetNS
|
||||
}
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
for _, targetNS := range namespaces {
|
||||
if targetNS != nil {
|
||||
targetNS.Close()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Describe("Testing with network foo and bar", func() {
|
||||
It("should isolate foo from bar", func() {
|
||||
var results [nsCount]*types100.Result
|
||||
for i := 0; i < nsCount; i++ {
|
||||
runtimeConfig := libcni.RuntimeConf{
|
||||
ContainerID: fmt.Sprintf("test-cni-firewall-%d", i),
|
||||
NetNS: namespaces[i].Path(),
|
||||
IfName: "eth0",
|
||||
}
|
||||
|
||||
configList := configListFoo
|
||||
switch i {
|
||||
case 0, 1:
|
||||
// leave foo
|
||||
default:
|
||||
configList = configListBar
|
||||
}
|
||||
|
||||
// Clean up garbages produced during past failed executions
|
||||
_ = cniConf.DelNetworkList(context.TODO(), configList, &runtimeConfig)
|
||||
|
||||
// Make delete idempotent, so we can clean up on failure
|
||||
netDeleted := false
|
||||
deleteNetwork := func() error {
|
||||
if netDeleted {
|
||||
return nil
|
||||
}
|
||||
netDeleted = true
|
||||
return cniConf.DelNetworkList(context.TODO(), configList, &runtimeConfig)
|
||||
}
|
||||
// Create the network
|
||||
res, err := cniConf.AddNetworkList(context.TODO(), configList, &runtimeConfig)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
// nolint: errcheck
|
||||
defer deleteNetwork()
|
||||
|
||||
results[i], err = types100.NewResultFromResult(res)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
fmt.Fprintf(GinkgoWriter, "results[%d]: %+v\n", i, results[i])
|
||||
}
|
||||
ping := func(src, dst int) error {
|
||||
return namespaces[src].Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
saddr := results[src].IPs[0].Address.IP.String()
|
||||
daddr := results[dst].IPs[0].Address.IP.String()
|
||||
srcNetName := results[src].Interfaces[0].Name
|
||||
dstNetName := results[dst].Interfaces[0].Name
|
||||
|
||||
fmt.Fprintf(GinkgoWriter, "ping %s (ns%d@%s) -> %s (ns%d@%s)...",
|
||||
saddr, src, srcNetName, daddr, dst, dstNetName)
|
||||
timeoutSec := 1
|
||||
if err := testutils.Ping(saddr, daddr, timeoutSec); err != nil {
|
||||
fmt.Fprintln(GinkgoWriter, "unpingable")
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(GinkgoWriter, "pingable")
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// ns0@foo can ping to ns1@foo
|
||||
err := ping(0, 1)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// ns1@foo can ping to ns0@foo
|
||||
err = ping(1, 0)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// ns0@foo cannot ping to ns2@bar
|
||||
err = ping(0, 2)
|
||||
Expect(err).To(HaveOccurred())
|
||||
|
||||
// ns1@foo cannot ping to ns2@bar
|
||||
err = ping(1, 2)
|
||||
Expect(err).To(HaveOccurred())
|
||||
|
||||
// ns2@bar cannot ping to ns0@foo
|
||||
err = ping(2, 0)
|
||||
Expect(err).To(HaveOccurred())
|
||||
|
||||
// ns2@bar cannot ping to ns1@foo
|
||||
err = ping(2, 1)
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
})
|
175
plugins/meta/firewall/ingresspolicy.go
Normal file
175
plugins/meta/firewall/ingresspolicy.go
Normal file
@ -0,0 +1,175 @@
|
||||
// Copyright 2022 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.
|
||||
|
||||
// This is a sample chained plugin that supports multiple CNI versions. It
|
||||
// parses prevResult according to the cniVersion
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
types100 "github.com/containernetworking/cni/pkg/types/100"
|
||||
"github.com/containernetworking/plugins/pkg/utils"
|
||||
"github.com/coreos/go-iptables/iptables"
|
||||
)
|
||||
|
||||
func setupIngressPolicy(conf *FirewallNetConf, prevResult *types100.Result) error {
|
||||
switch conf.IngressPolicy {
|
||||
case "", IngressPolicyOpen:
|
||||
// NOP
|
||||
return nil
|
||||
case IngressPolicySameBridge:
|
||||
return setupIngressPolicySameBridge(conf, prevResult)
|
||||
default:
|
||||
return fmt.Errorf("unknown ingress policy: %q", conf.IngressPolicy)
|
||||
}
|
||||
}
|
||||
|
||||
func setupIngressPolicySameBridge(conf *FirewallNetConf, prevResult *types100.Result) error {
|
||||
if len(prevResult.Interfaces) == 0 {
|
||||
return fmt.Errorf("interface needs to be set for ingress policy %q, make sure to chain \"firewall\" plugin with \"bridge\"",
|
||||
conf.IngressPolicy)
|
||||
}
|
||||
intf := prevResult.Interfaces[0]
|
||||
if intf == nil {
|
||||
return fmt.Errorf("got nil interface")
|
||||
}
|
||||
bridgeName := intf.Name
|
||||
if bridgeName == "" {
|
||||
return fmt.Errorf("got empty bridge name")
|
||||
}
|
||||
for _, iptProto := range findProtos(conf) {
|
||||
ipt, err := iptables.NewWithProtocol(iptProto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := setupIsolationChains(ipt, bridgeName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func teardownIngressPolicy(conf *FirewallNetConf, prevResult *types100.Result) error {
|
||||
switch conf.IngressPolicy {
|
||||
case "", IngressPolicyOpen:
|
||||
// NOP
|
||||
return nil
|
||||
case IngressPolicySameBridge:
|
||||
// NOP
|
||||
//
|
||||
// We can't be sure whether conf.bridgeName is still in use by other containers.
|
||||
// So we do not remove the iptable rules that are created per bridge.
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("unknown ingress policy: %q", conf.IngressPolicy)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
filterTableName = "filter" // built-in
|
||||
forwardChainName = "FORWARD" // built-in
|
||||
)
|
||||
|
||||
// setupIsolationChains executes the following iptables commands for isolating networks:
|
||||
// ```
|
||||
// iptables -N CNI-ISOLATION-STAGE-1
|
||||
// iptables -N CNI-ISOLATION-STAGE-2
|
||||
// # NOTE: "-j CNI-ISOLATION-STAGE-1" needs to be before "CNI-FORWARD" chain. So we use -I here.
|
||||
// iptables -I FORWARD -j CNI-ISOLATION-STAGE-1
|
||||
// iptables -A CNI-ISOLATION-STAGE-1 -i ${bridgeName} ! -o ${bridgeName} -j CNI-ISOLATION-STAGE-2
|
||||
// iptables -A CNI-ISOLATION-STAGE-1 -j RETURN
|
||||
// iptables -A CNI-ISOLATION-STAGE-2 -o ${bridgeName} -j DROP
|
||||
// iptables -A CNI-ISOLATION-STAGE-2 -j RETURN
|
||||
// ```
|
||||
func setupIsolationChains(ipt *iptables.IPTables, bridgeName string) error {
|
||||
const (
|
||||
// Future version may support custom chain names
|
||||
stage1Chain = "CNI-ISOLATION-STAGE-1"
|
||||
stage2Chain = "CNI-ISOLATION-STAGE-2"
|
||||
)
|
||||
// Commands:
|
||||
// ```
|
||||
// iptables -N CNI-ISOLATION-STAGE-1
|
||||
// iptables -N CNI-ISOLATION-STAGE-2
|
||||
// ```
|
||||
for _, chain := range []string{stage1Chain, stage2Chain} {
|
||||
if err := utils.EnsureChain(ipt, filterTableName, chain); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Commands:
|
||||
// ```
|
||||
// iptables -I FORWARD -j CNI-ISOLATION-STAGE-1
|
||||
// ```
|
||||
jumpToStage1 := withDefaultComment([]string{"-j", stage1Chain})
|
||||
// NOTE: "-j CNI-ISOLATION-STAGE-1" needs to be before "CNI-FORWARD" created by CNI firewall plugin.
|
||||
// So we specify prepend = true .
|
||||
const jumpToStage1Prepend = true
|
||||
if err := utils.InsertUnique(ipt, filterTableName, forwardChainName, jumpToStage1Prepend, jumpToStage1); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Commands:
|
||||
// ```
|
||||
// iptables -A CNI-ISOLATION-STAGE-1 -i ${bridgeName} ! -o ${bridgeName} -j CNI-ISOLATION-STAGE-2
|
||||
// iptables -A CNI-ISOLATION-STAGE-1 -j RETURN
|
||||
// ```
|
||||
stage1Bridge := withDefaultComment(isolationStage1BridgeRule(bridgeName, stage2Chain))
|
||||
// prepend = true because this needs to be before "-j RETURN"
|
||||
const stage1BridgePrepend = true
|
||||
if err := utils.InsertUnique(ipt, filterTableName, stage1Chain, stage1BridgePrepend, stage1Bridge); err != nil {
|
||||
return err
|
||||
}
|
||||
stage1Return := withDefaultComment([]string{"-j", "RETURN"})
|
||||
if err := utils.InsertUnique(ipt, filterTableName, stage1Chain, false, stage1Return); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Commands:
|
||||
// ```
|
||||
// iptables -A CNI-ISOLATION-STAGE-2 -o ${bridgeName} -j DROP
|
||||
// iptables -A CNI-ISOLATION-STAGE-2 -j RETURN
|
||||
// ```
|
||||
stage2Bridge := withDefaultComment(isolationStage2BridgeRule(bridgeName))
|
||||
// prepend = true because this needs to be before "-j RETURN"
|
||||
const stage2BridgePrepend = true
|
||||
if err := utils.InsertUnique(ipt, filterTableName, stage2Chain, stage2BridgePrepend, stage2Bridge); err != nil {
|
||||
return err
|
||||
}
|
||||
stage2Return := withDefaultComment([]string{"-j", "RETURN"})
|
||||
if err := utils.InsertUnique(ipt, filterTableName, stage2Chain, false, stage2Return); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func isolationStage1BridgeRule(bridgeName, stage2Chain string) []string {
|
||||
return []string{"-i", bridgeName, "!", "-o", bridgeName, "-j", stage2Chain}
|
||||
}
|
||||
|
||||
func isolationStage2BridgeRule(bridgeName string) []string {
|
||||
return []string{"-o", bridgeName, "-j", "DROP"}
|
||||
}
|
||||
|
||||
func withDefaultComment(rule []string) []string {
|
||||
defaultComment := fmt.Sprintf("CNI firewall plugin rules (ingressPolicy: same-bridge)")
|
||||
return withComment(rule, defaultComment)
|
||||
}
|
||||
|
||||
func withComment(rule []string, comment string) []string {
|
||||
return append(rule, []string{"-m", "comment", "--comment", comment}...)
|
||||
}
|
@ -44,7 +44,7 @@ func (c *chain) setup(ipt *iptables.IPTables) error {
|
||||
|
||||
// Add the rules to the chain
|
||||
for _, rule := range c.rules {
|
||||
if err := insertUnique(ipt, c.table, c.name, false, rule); err != nil {
|
||||
if err := utils.InsertUnique(ipt, c.table, c.name, false, rule); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -55,7 +55,7 @@ func (c *chain) setup(ipt *iptables.IPTables) error {
|
||||
r := []string{}
|
||||
r = append(r, rule...)
|
||||
r = append(r, "-j", c.name)
|
||||
if err := insertUnique(ipt, c.table, entryChain, c.prependEntry, r); err != nil {
|
||||
if err := utils.InsertUnique(ipt, c.table, entryChain, c.prependEntry, r); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -101,24 +101,6 @@ func (c *chain) teardown(ipt *iptables.IPTables) error {
|
||||
return utils.DeleteChain(ipt, c.table, c.name)
|
||||
}
|
||||
|
||||
// insertUnique will add a rule to a chain if it does not already exist.
|
||||
// By default the rule is appended, unless prepend is true.
|
||||
func insertUnique(ipt *iptables.IPTables, table, chain string, prepend bool, rule []string) error {
|
||||
exists, err := ipt.Exists(table, chain, rule...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
if prepend {
|
||||
return ipt.Insert(table, chain, 1, rule...)
|
||||
} else {
|
||||
return ipt.Append(table, chain, rule...)
|
||||
}
|
||||
}
|
||||
|
||||
// check the chain.
|
||||
func (c *chain) check(ipt *iptables.IPTables) error {
|
||||
|
||||
|
@ -127,26 +127,12 @@ func checkPorts(config *PortMapConf, containerNet net.IPNet) error {
|
||||
}
|
||||
|
||||
if ip4t != nil {
|
||||
exists, err := utils.ChainExists(ip4t, dnatChain.table, dnatChain.name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exists {
|
||||
return err
|
||||
}
|
||||
if err := dnatChain.check(ip4t); err != nil {
|
||||
return fmt.Errorf("could not check ipv4 dnat: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if ip6t != nil {
|
||||
exists, err := utils.ChainExists(ip6t, dnatChain.table, dnatChain.name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exists {
|
||||
return err
|
||||
}
|
||||
if err := dnatChain.check(ip6t); err != nil {
|
||||
return fmt.Errorf("could not check ipv6 dnat: %v", err)
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/j-keck/arping"
|
||||
"github.com/vishvananda/netlink"
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
@ -315,18 +314,17 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
return err
|
||||
}
|
||||
|
||||
result, err := current.NewResultFromResult(tuningConf.PrevResult)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// The directory /proc/sys/net is per network namespace. Enter in the
|
||||
// network namespace before writing on it.
|
||||
|
||||
err = ns.WithNetNSPath(args.Netns, func(_ ns.NetNS) error {
|
||||
for key, value := range tuningConf.SysCtl {
|
||||
// If the key contains `IFNAME` - substitute it with args.IfName
|
||||
// to allow setting sysctls on a particular interface, on which
|
||||
// other operations (like mac/mtu setting) are performed
|
||||
key = strings.Replace(key, "IFNAME", args.IfName, 1)
|
||||
|
||||
fileName := filepath.Join("/proc/sys", strings.Replace(key, ".", "/", -1))
|
||||
fileName = filepath.Clean(fileName)
|
||||
|
||||
// Refuse to modify sysctl parameters that don't belong
|
||||
// to the network subsystem.
|
||||
@ -351,12 +349,6 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, ipc := range result.IPs {
|
||||
if ipc.Address.IP.To4() != nil {
|
||||
_ = arping.GratuitousArpOverIfaceByName(ipc.Address.IP, args.IfName)
|
||||
}
|
||||
}
|
||||
|
||||
updateResultsMacAddr(tuningConf, args.IfName, tuningConf.Mac)
|
||||
}
|
||||
|
||||
@ -428,7 +420,6 @@ func cmdCheck(args *skel.CmdArgs) error {
|
||||
// Check each configured value vs what's currently in the container
|
||||
for key, confValue := range tuningConf.SysCtl {
|
||||
fileName := filepath.Join("/proc/sys", strings.Replace(key, ".", "/", -1))
|
||||
fileName = filepath.Clean(fileName)
|
||||
|
||||
contents, err := ioutil.ReadFile(fileName)
|
||||
if err != nil {
|
||||
|
@ -123,6 +123,17 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// if NetNs is passed down by the Cloud Orchestration Engine, or if it called multiple times
|
||||
// so don't return an error if the device is already removed.
|
||||
// https://github.com/kubernetes/kubernetes/issues/43014#issuecomment-287164444
|
||||
_, ok := err.(ns.NSPathNotExistErr)
|
||||
if ok {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("cmdDel failed: %v", err)
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ rm -Rf ${SRC_DIR}/${RELEASE_DIR}
|
||||
mkdir -p ${SRC_DIR}/${RELEASE_DIR}
|
||||
mkdir -p ${OUTPUT_DIR}
|
||||
|
||||
$DOCKER run -ti -v ${SRC_DIR}:/go/src/github.com/containernetworking/plugins:z --rm golang:1.16-alpine \
|
||||
$DOCKER run -ti -v ${SRC_DIR}:/go/src/github.com/containernetworking/plugins:z --rm golang:1.17-alpine \
|
||||
/bin/sh -xe -c "\
|
||||
apk --no-cache add bash tar;
|
||||
cd /go/src/github.com/containernetworking/plugins; umask 0022;
|
||||
|
9
vendor/github.com/Microsoft/go-winio/go.mod
generated
vendored
9
vendor/github.com/Microsoft/go-winio/go.mod
generated
vendored
@ -1,9 +0,0 @@
|
||||
module github.com/Microsoft/go-winio
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/sirupsen/logrus v1.7.0
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
|
||||
)
|
14
vendor/github.com/Microsoft/go-winio/go.sum
generated
vendored
14
vendor/github.com/Microsoft/go-winio/go.sum
generated
vendored
@ -1,14 +0,0 @@
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
27
vendor/github.com/Microsoft/hcsshim/go.mod
generated
vendored
27
vendor/github.com/Microsoft/hcsshim/go.mod
generated
vendored
@ -1,27 +0,0 @@
|
||||
module github.com/Microsoft/hcsshim
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.4.17
|
||||
github.com/containerd/cgroups v1.0.1
|
||||
github.com/containerd/console v1.0.2
|
||||
github.com/containerd/containerd v1.5.1
|
||||
github.com/containerd/go-runc v1.0.0
|
||||
github.com/containerd/ttrpc v1.0.2
|
||||
github.com/containerd/typeurl v1.0.2
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/sirupsen/logrus v1.7.0
|
||||
github.com/urfave/cli v1.22.2
|
||||
go.opencensus.io v0.22.3
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492
|
||||
google.golang.org/grpc v1.33.2
|
||||
)
|
||||
|
||||
replace (
|
||||
google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63
|
||||
google.golang.org/grpc => google.golang.org/grpc v1.27.1
|
||||
)
|
885
vendor/github.com/Microsoft/hcsshim/go.sum
generated
vendored
885
vendor/github.com/Microsoft/hcsshim/go.sum
generated
vendored
@ -1,885 +0,0 @@
|
||||
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
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/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/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/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/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=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
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/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/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||
github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.4.17 h1:iT12IBVClFevaf8PuVyi3UmZOVh4OqnaLxDTW2O6j3w=
|
||||
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
||||
github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
||||
github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
|
||||
github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
|
||||
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
|
||||
github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
|
||||
github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
|
||||
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
|
||||
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
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/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
|
||||
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
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/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
|
||||
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||
github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
|
||||
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
|
||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
|
||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
|
||||
github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
|
||||
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
|
||||
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
|
||||
github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=
|
||||
github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
||||
github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
||||
github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E=
|
||||
github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=
|
||||
github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=
|
||||
github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI=
|
||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
|
||||
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=
|
||||
github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
||||
github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
||||
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
|
||||
github.com/containerd/cgroups v1.0.1 h1:iJnMvco9XGvKUvNQkv88bE4uJXxRQH18efbKo9w5vHQ=
|
||||
github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU=
|
||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||
github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||
github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
|
||||
github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw=
|
||||
github.com/containerd/console v1.0.2 h1:Pi6D+aZXM+oUw1czuKgH5IJ+y0jhYcwBJfx5/Ghn9dE=
|
||||
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
|
||||
github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.4.0-beta.2.0.20200729163537-40b22ef07410/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ=
|
||||
github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU=
|
||||
github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI=
|
||||
github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
|
||||
github.com/containerd/containerd v1.5.1 h1:xWHPAoe6VkUiI9GAvndJM7s/0MTrmwX3AQiYTr3olf0=
|
||||
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
|
||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=
|
||||
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
|
||||
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
|
||||
github.com/containerd/continuity v0.1.0 h1:UFRRY5JemiAhPZrr/uE0n8fMTLcZsUvySPr1+D7pgr8=
|
||||
github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
|
||||
github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
||||
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
||||
github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
|
||||
github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
|
||||
github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
|
||||
github.com/containerd/fifo v1.0.0 h1:6PirWBr9/L7GDamKr+XM0IeUFXu5mf3M/BPpH9gaLBU=
|
||||
github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
|
||||
github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU=
|
||||
github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk=
|
||||
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
||||
github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
||||
github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g=
|
||||
github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
|
||||
github.com/containerd/go-runc v1.0.0 h1:oU+lLv1ULm5taqgV/CJivypVODI4SUz1znWjv3nNYS0=
|
||||
github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
|
||||
github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0=
|
||||
github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA=
|
||||
github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow=
|
||||
github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms=
|
||||
github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c=
|
||||
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
|
||||
github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
|
||||
github.com/containerd/ttrpc v1.0.2 h1:2/O3oTZN36q2xRolk0a2WWGgh7/Vf/liElg5hFYLX9U=
|
||||
github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
|
||||
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
|
||||
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk=
|
||||
github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=
|
||||
github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY=
|
||||
github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s=
|
||||
github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw=
|
||||
github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y=
|
||||
github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
|
||||
github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
|
||||
github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
|
||||
github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM=
|
||||
github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=
|
||||
github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
|
||||
github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4=
|
||||
github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||
github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||
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-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
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/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||
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/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
||||
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
|
||||
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
|
||||
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
|
||||
github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
||||
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
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/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||
github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
|
||||
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||
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.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+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/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
|
||||
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
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=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
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-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
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/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/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||
github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
|
||||
github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
|
||||
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.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
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 h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
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/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/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/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=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
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/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.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.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
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/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/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/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
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/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
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-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/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
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/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/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
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.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
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/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/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
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.2/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/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 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
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 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
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/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||
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/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
|
||||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
github.com/moby/sys/mountinfo v0.4.1 h1:1O+1cHA1aujwEwwVMa2Xm2l+gIpUHyd3+D+d7LZh1kM=
|
||||
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
|
||||
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
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/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
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=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
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-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
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.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.3/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/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
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.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
|
||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
|
||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d h1:pNa8metDkwZjb9g4T8s+krQ+HRgZAkqnXml+wNir/+s=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
||||
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
|
||||
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||
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-0.20171018195549-f15c970de5b7/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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
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.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
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.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
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.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||
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/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
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 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
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/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
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-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
|
||||
github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
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 v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
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.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
||||
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/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
|
||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
||||
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.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
|
||||
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 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=
|
||||
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.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/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-20190701094942-4def268fd1a4/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-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
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/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=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
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/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
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-20190619014844-b5b0513f8c1b/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-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-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
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-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/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-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
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/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
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-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 h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/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-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/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-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/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-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492 h1:Paq34FxTluEPvVyayQqMPgHm+vTOrIifmcYxFBx9TLg=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
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 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
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-20200630173020-3af7569d3a1e/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-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
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-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
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-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
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=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
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.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
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/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63 h1:YzfoEYWbODU5Fbt37+h7X16BWQbad7Q4S6gclTKFXM8=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
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=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
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-20141024133853-64131543e789/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 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
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=
|
||||
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
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.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=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
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.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
|
||||
k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
|
||||
k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
|
||||
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
|
||||
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
|
||||
k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
|
||||
k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
|
||||
k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
|
||||
k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=
|
||||
k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=
|
||||
k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
|
||||
k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
|
||||
k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
|
||||
k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM=
|
||||
k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
|
||||
k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
|
||||
k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc=
|
||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
|
||||
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/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.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
5
vendor/github.com/alexflint/go-filemutex/go.mod
generated
vendored
5
vendor/github.com/alexflint/go-filemutex/go.mod
generated
vendored
@ -1,5 +0,0 @@
|
||||
module github.com/alexflint/go-filemutex
|
||||
|
||||
go 1.13
|
||||
|
||||
require github.com/stretchr/testify v1.4.0
|
11
vendor/github.com/alexflint/go-filemutex/go.sum
generated
vendored
11
vendor/github.com/alexflint/go-filemutex/go.sum
generated
vendored
@ -1,11 +0,0 @@
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
4
vendor/github.com/buger/jsonparser/go.mod
generated
vendored
4
vendor/github.com/buger/jsonparser/go.mod
generated
vendored
@ -1,4 +0,0 @@
|
||||
module github.com/buger/jsonparser
|
||||
|
||||
go 1.13
|
||||
|
0
vendor/github.com/buger/jsonparser/go.sum
generated
vendored
0
vendor/github.com/buger/jsonparser/go.sum
generated
vendored
5
vendor/github.com/fsnotify/fsnotify/go.mod
generated
vendored
5
vendor/github.com/fsnotify/fsnotify/go.mod
generated
vendored
@ -1,5 +0,0 @@
|
||||
module github.com/fsnotify/fsnotify
|
||||
|
||||
go 1.13
|
||||
|
||||
require golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9
|
2
vendor/github.com/fsnotify/fsnotify/go.sum
generated
vendored
2
vendor/github.com/fsnotify/fsnotify/go.sum
generated
vendored
@ -1,2 +0,0 @@
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
3
vendor/github.com/godbus/dbus/v5/go.mod
generated
vendored
3
vendor/github.com/godbus/dbus/v5/go.mod
generated
vendored
@ -1,3 +0,0 @@
|
||||
module github.com/godbus/dbus/v5
|
||||
|
||||
go 1.12
|
0
vendor/github.com/godbus/dbus/v5/go.sum
generated
vendored
0
vendor/github.com/godbus/dbus/v5/go.sum
generated
vendored
1
vendor/github.com/j-keck/arping/.gitignore
generated
vendored
1
vendor/github.com/j-keck/arping/.gitignore
generated
vendored
@ -1 +0,0 @@
|
||||
arping
|
22
vendor/github.com/j-keck/arping/LICENSE
generated
vendored
22
vendor/github.com/j-keck/arping/LICENSE
generated
vendored
@ -1,22 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2016 j-keck [jhyphenkeck@gmail.com]
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
31
vendor/github.com/j-keck/arping/README.md
generated
vendored
31
vendor/github.com/j-keck/arping/README.md
generated
vendored
@ -1,31 +0,0 @@
|
||||
[](https://pkg.go.dev/github.com/j-keck/arping)
|
||||
|
||||
# arping
|
||||
|
||||
arping is a native go library to ping a host per arp datagram, or query a host mac address
|
||||
|
||||
The currently supported platforms are: Linux and BSD.
|
||||
|
||||
|
||||
## Usage
|
||||
### arping library
|
||||
|
||||
* import this library per `import "github.com/j-keck/arping"`
|
||||
* export GOPATH if not already (`export GOPATH=$PWD`)
|
||||
* download the library `go get`
|
||||
* run it `sudo -E go run <YOUR PROGRAMM>`
|
||||
* or build it `go build`
|
||||
|
||||
|
||||
The library requires raw socket access. So it must run as root, or with appropriate capabilities under linux: `sudo setcap cap_net_raw+ep <BIN>`.
|
||||
|
||||
For api doc and examples see: [godoc](http://godoc.org/github.com/j-keck/arping) or check the standalone under 'cmd/arping/main.go'.
|
||||
|
||||
|
||||
|
||||
### arping executable
|
||||
|
||||
To get a runnable pinger use `go get -u github.com/j-keck/arping/cmd/arping`. This will build the binary in $GOPATH/bin.
|
||||
|
||||
arping requires raw socket access. So it must run as root, or with appropriate capabilities under Linux: `sudo setcap cap_net_raw+ep <ARPING_PATH>`.
|
||||
|
98
vendor/github.com/j-keck/arping/arp_datagram.go
generated
vendored
98
vendor/github.com/j-keck/arping/arp_datagram.go
generated
vendored
@ -1,98 +0,0 @@
|
||||
package arping
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"net"
|
||||
)
|
||||
|
||||
const (
|
||||
requestOper = 1
|
||||
responseOper = 2
|
||||
)
|
||||
|
||||
type arpDatagram struct {
|
||||
htype uint16 // Hardware Type
|
||||
ptype uint16 // Protocol Type
|
||||
hlen uint8 // Hardware address Length
|
||||
plen uint8 // Protocol address length
|
||||
oper uint16 // Operation 1->request, 2->response
|
||||
sha []byte // Sender hardware address, length from Hlen
|
||||
spa []byte // Sender protocol address, length from Plen
|
||||
tha []byte // Target hardware address, length from Hlen
|
||||
tpa []byte // Target protocol address, length from Plen
|
||||
}
|
||||
|
||||
func newArpRequest(
|
||||
srcMac net.HardwareAddr,
|
||||
srcIP net.IP,
|
||||
dstMac net.HardwareAddr,
|
||||
dstIP net.IP) arpDatagram {
|
||||
return arpDatagram{
|
||||
htype: uint16(1),
|
||||
ptype: uint16(0x0800),
|
||||
hlen: uint8(6),
|
||||
plen: uint8(4),
|
||||
oper: uint16(requestOper),
|
||||
sha: srcMac,
|
||||
spa: srcIP.To4(),
|
||||
tha: dstMac,
|
||||
tpa: dstIP.To4()}
|
||||
}
|
||||
|
||||
func (datagram arpDatagram) Marshal() []byte {
|
||||
buf := new(bytes.Buffer)
|
||||
binary.Write(buf, binary.BigEndian, datagram.htype)
|
||||
binary.Write(buf, binary.BigEndian, datagram.ptype)
|
||||
binary.Write(buf, binary.BigEndian, datagram.hlen)
|
||||
binary.Write(buf, binary.BigEndian, datagram.plen)
|
||||
binary.Write(buf, binary.BigEndian, datagram.oper)
|
||||
buf.Write(datagram.sha)
|
||||
buf.Write(datagram.spa)
|
||||
buf.Write(datagram.tha)
|
||||
buf.Write(datagram.tpa)
|
||||
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func (datagram arpDatagram) MarshalWithEthernetHeader() []byte {
|
||||
// ethernet frame header
|
||||
var ethernetHeader []byte
|
||||
ethernetHeader = append(ethernetHeader, datagram.tha...)
|
||||
ethernetHeader = append(ethernetHeader, datagram.sha...)
|
||||
ethernetHeader = append(ethernetHeader, []byte{0x08, 0x06}...) // arp
|
||||
|
||||
return append(ethernetHeader, datagram.Marshal()...)
|
||||
}
|
||||
|
||||
func (datagram arpDatagram) SenderIP() net.IP {
|
||||
return net.IP(datagram.spa)
|
||||
}
|
||||
func (datagram arpDatagram) SenderMac() net.HardwareAddr {
|
||||
return net.HardwareAddr(datagram.sha)
|
||||
}
|
||||
|
||||
func (datagram arpDatagram) IsResponseOf(request arpDatagram) bool {
|
||||
return datagram.oper == responseOper && bytes.Equal(request.spa, datagram.tpa) &&
|
||||
bytes.Equal(request.tpa, datagram.spa)
|
||||
}
|
||||
|
||||
func parseArpDatagram(buffer []byte) arpDatagram {
|
||||
var datagram arpDatagram
|
||||
|
||||
b := bytes.NewBuffer(buffer)
|
||||
binary.Read(b, binary.BigEndian, &datagram.htype)
|
||||
binary.Read(b, binary.BigEndian, &datagram.ptype)
|
||||
binary.Read(b, binary.BigEndian, &datagram.hlen)
|
||||
binary.Read(b, binary.BigEndian, &datagram.plen)
|
||||
binary.Read(b, binary.BigEndian, &datagram.oper)
|
||||
|
||||
haLen := int(datagram.hlen)
|
||||
paLen := int(datagram.plen)
|
||||
datagram.sha = b.Next(haLen)
|
||||
datagram.spa = b.Next(paLen)
|
||||
datagram.tha = b.Next(haLen)
|
||||
datagram.tpa = b.Next(paLen)
|
||||
|
||||
return datagram
|
||||
}
|
233
vendor/github.com/j-keck/arping/arping.go
generated
vendored
233
vendor/github.com/j-keck/arping/arping.go
generated
vendored
@ -1,233 +0,0 @@
|
||||
// Package arping is a native go library to ping a host per arp datagram, or query a host mac address
|
||||
//
|
||||
// The currently supported platforms are: Linux and BSD.
|
||||
//
|
||||
//
|
||||
// The library requires raw socket access. So it must run as root, or with appropriate capabilities under linux:
|
||||
// `sudo setcap cap_net_raw+ep <BIN>`.
|
||||
//
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// ping a host:
|
||||
// ------------
|
||||
// package main
|
||||
// import ("fmt"; "github.com/j-keck/arping"; "net")
|
||||
//
|
||||
// func main(){
|
||||
// dstIP := net.ParseIP("192.168.1.1")
|
||||
// if hwAddr, duration, err := arping.Ping(dstIP); err != nil {
|
||||
// fmt.Println(err)
|
||||
// } else {
|
||||
// fmt.Printf("%s (%s) %d usec\n", dstIP, hwAddr, duration/1000)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// resolve mac address:
|
||||
// --------------------
|
||||
// package main
|
||||
// import ("fmt"; "github.com/j-keck/arping"; "net")
|
||||
//
|
||||
// func main(){
|
||||
// dstIP := net.ParseIP("192.168.1.1")
|
||||
// if hwAddr, _, err := arping.Ping(dstIP); err != nil {
|
||||
// fmt.Println(err)
|
||||
// } else {
|
||||
// fmt.Printf("%s is at %s\n", dstIP, hwAddr)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// check if host is online:
|
||||
// ------------------------
|
||||
// package main
|
||||
// import ("fmt"; "github.com/j-keck/arping"; "net")
|
||||
//
|
||||
// func main(){
|
||||
// dstIP := net.ParseIP("192.168.1.1")
|
||||
// _, _, err := arping.Ping(dstIP)
|
||||
// if err == arping.ErrTimeout {
|
||||
// fmt.Println("offline")
|
||||
// }else if err != nil {
|
||||
// fmt.Println(err.Error())
|
||||
// }else{
|
||||
// fmt.Println("online")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
package arping
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrTimeout error
|
||||
ErrTimeout = errors.New("timeout")
|
||||
|
||||
verboseLog = log.New(ioutil.Discard, "", 0)
|
||||
timeout = time.Duration(500 * time.Millisecond)
|
||||
)
|
||||
|
||||
// Ping sends an arp ping to 'dstIP'
|
||||
func Ping(dstIP net.IP) (net.HardwareAddr, time.Duration, error) {
|
||||
if err := validateIP(dstIP); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
iface, err := findUsableInterfaceForNetwork(dstIP)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return PingOverIface(dstIP, *iface)
|
||||
}
|
||||
|
||||
// PingOverIfaceByName sends an arp ping over interface name 'ifaceName' to 'dstIP'
|
||||
func PingOverIfaceByName(dstIP net.IP, ifaceName string) (net.HardwareAddr, time.Duration, error) {
|
||||
if err := validateIP(dstIP); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
iface, err := net.InterfaceByName(ifaceName)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return PingOverIface(dstIP, *iface)
|
||||
}
|
||||
|
||||
// PingOverIface sends an arp ping over interface 'iface' to 'dstIP'
|
||||
func PingOverIface(dstIP net.IP, iface net.Interface) (net.HardwareAddr, time.Duration, error) {
|
||||
if err := validateIP(dstIP); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
srcMac := iface.HardwareAddr
|
||||
srcIP, err := findIPInNetworkFromIface(dstIP, iface)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
broadcastMac := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
|
||||
request := newArpRequest(srcMac, srcIP, broadcastMac, dstIP)
|
||||
|
||||
sock, err := initialize(iface)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
defer sock.deinitialize()
|
||||
|
||||
type PingResult struct {
|
||||
mac net.HardwareAddr
|
||||
duration time.Duration
|
||||
err error
|
||||
}
|
||||
pingResultChan := make(chan PingResult, 1)
|
||||
|
||||
go func() {
|
||||
// send arp request
|
||||
verboseLog.Printf("arping '%s' over interface: '%s' with address: '%s'\n", dstIP, iface.Name, srcIP)
|
||||
if sendTime, err := sock.send(request); err != nil {
|
||||
pingResultChan <- PingResult{nil, 0, err}
|
||||
} else {
|
||||
for {
|
||||
// receive arp response
|
||||
response, receiveTime, err := sock.receive()
|
||||
|
||||
if err != nil {
|
||||
pingResultChan <- PingResult{nil, 0, err}
|
||||
return
|
||||
}
|
||||
|
||||
if response.IsResponseOf(request) {
|
||||
duration := receiveTime.Sub(sendTime)
|
||||
verboseLog.Printf("process received arp: srcIP: '%s', srcMac: '%s'\n",
|
||||
response.SenderIP(), response.SenderMac())
|
||||
pingResultChan <- PingResult{response.SenderMac(), duration, err}
|
||||
return
|
||||
}
|
||||
|
||||
verboseLog.Printf("ignore received arp: srcIP: '%s', srcMac: '%s'\n",
|
||||
response.SenderIP(), response.SenderMac())
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case pingResult := <-pingResultChan:
|
||||
return pingResult.mac, pingResult.duration, pingResult.err
|
||||
case <-time.After(timeout):
|
||||
sock.deinitialize()
|
||||
return nil, 0, ErrTimeout
|
||||
}
|
||||
}
|
||||
|
||||
// GratuitousArp sends an gratuitous arp from 'srcIP'
|
||||
func GratuitousArp(srcIP net.IP) error {
|
||||
if err := validateIP(srcIP); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
iface, err := findUsableInterfaceForNetwork(srcIP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return GratuitousArpOverIface(srcIP, *iface)
|
||||
}
|
||||
|
||||
// GratuitousArpOverIfaceByName sends an gratuitous arp over interface name 'ifaceName' from 'srcIP'
|
||||
func GratuitousArpOverIfaceByName(srcIP net.IP, ifaceName string) error {
|
||||
if err := validateIP(srcIP); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
iface, err := net.InterfaceByName(ifaceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return GratuitousArpOverIface(srcIP, *iface)
|
||||
}
|
||||
|
||||
// GratuitousArpOverIface sends an gratuitous arp over interface 'iface' from 'srcIP'
|
||||
func GratuitousArpOverIface(srcIP net.IP, iface net.Interface) error {
|
||||
if err := validateIP(srcIP); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
srcMac := iface.HardwareAddr
|
||||
broadcastMac := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
|
||||
request := newArpRequest(srcMac, srcIP, broadcastMac, srcIP)
|
||||
|
||||
sock, err := initialize(iface)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer sock.deinitialize()
|
||||
verboseLog.Printf("gratuitous arp over interface: '%s' with address: '%s'\n", iface.Name, srcIP)
|
||||
_, err = sock.send(request)
|
||||
return err
|
||||
}
|
||||
|
||||
// EnableVerboseLog enables verbose logging on stdout
|
||||
func EnableVerboseLog() {
|
||||
verboseLog = log.New(os.Stdout, "", 0)
|
||||
}
|
||||
|
||||
// SetTimeout sets ping timeout
|
||||
func SetTimeout(t time.Duration) {
|
||||
timeout = t
|
||||
}
|
||||
|
||||
func validateIP(ip net.IP) error {
|
||||
// ip must be a valid V4 address
|
||||
if len(ip.To4()) != net.IPv4len {
|
||||
return fmt.Errorf("not a valid v4 Address: %s", ip)
|
||||
}
|
||||
return nil
|
||||
}
|
104
vendor/github.com/j-keck/arping/arping_bsd.go
generated
vendored
104
vendor/github.com/j-keck/arping/arping_bsd.go
generated
vendored
@ -1,104 +0,0 @@
|
||||
// +build darwin freebsd openbsd
|
||||
|
||||
package arping
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
type BsdSocket struct {
|
||||
bpf *os.File
|
||||
bpfFd int
|
||||
buflen int
|
||||
}
|
||||
|
||||
var bpfArpFilter = []syscall.BpfInsn{
|
||||
// make sure this is an arp packet
|
||||
*syscall.BpfStmt(syscall.BPF_LD+syscall.BPF_H+syscall.BPF_ABS, 12),
|
||||
*syscall.BpfJump(syscall.BPF_JMP+syscall.BPF_JEQ+syscall.BPF_K, 0x0806, 0, 1),
|
||||
// if we passed all the tests, ask for the whole packet.
|
||||
*syscall.BpfStmt(syscall.BPF_RET+syscall.BPF_K, -1),
|
||||
// otherwise, drop it.
|
||||
*syscall.BpfStmt(syscall.BPF_RET+syscall.BPF_K, 0),
|
||||
}
|
||||
|
||||
func initialize(iface net.Interface) (s *BsdSocket, err error) {
|
||||
s = &BsdSocket{}
|
||||
verboseLog.Println("search available /dev/bpfX")
|
||||
for i := 0; i <= 10; i++ {
|
||||
bpfPath := fmt.Sprintf("/dev/bpf%d", i)
|
||||
s.bpf, err = os.OpenFile(bpfPath, os.O_RDWR, 0666)
|
||||
if err != nil {
|
||||
verboseLog.Printf(" open failed: %s - %s\n", bpfPath, err.Error())
|
||||
} else {
|
||||
verboseLog.Printf(" open success: %s\n", bpfPath)
|
||||
break
|
||||
}
|
||||
}
|
||||
s.bpfFd = int(s.bpf.Fd())
|
||||
if s.bpfFd == -1 {
|
||||
return s, errors.New("unable to open /dev/bpfX")
|
||||
}
|
||||
|
||||
if err := syscall.SetBpfInterface(s.bpfFd, iface.Name); err != nil {
|
||||
return s, err
|
||||
}
|
||||
|
||||
if err := syscall.SetBpfImmediate(s.bpfFd, 1); err != nil {
|
||||
return s, err
|
||||
}
|
||||
|
||||
s.buflen, err = syscall.BpfBuflen(s.bpfFd)
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
|
||||
if err := syscall.SetBpf(s.bpfFd, bpfArpFilter); err != nil {
|
||||
return s, err
|
||||
}
|
||||
|
||||
if err := syscall.FlushBpf(s.bpfFd); err != nil {
|
||||
return s, err
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *BsdSocket) send(request arpDatagram) (time.Time, error) {
|
||||
_, err := syscall.Write(s.bpfFd, request.MarshalWithEthernetHeader())
|
||||
return time.Now(), err
|
||||
}
|
||||
|
||||
func (s *BsdSocket) receive() (arpDatagram, time.Time, error) {
|
||||
buffer := make([]byte, s.buflen)
|
||||
n, err := syscall.Read(s.bpfFd, buffer)
|
||||
if err != nil {
|
||||
return arpDatagram{}, time.Now(), err
|
||||
}
|
||||
|
||||
//
|
||||
// FreeBSD uses a different bpf header (bh_tstamp differ in it's size)
|
||||
// https://www.freebsd.org/cgi/man.cgi?bpf(4)#BPF_HEADER
|
||||
//
|
||||
var bpfHdrLength int
|
||||
if runtime.GOOS == "freebsd" {
|
||||
bpfHdrLength = 26
|
||||
} else {
|
||||
bpfHdrLength = 18
|
||||
}
|
||||
|
||||
// skip bpf header + 14 bytes ethernet header
|
||||
var hdrLength = bpfHdrLength + 14
|
||||
|
||||
return parseArpDatagram(buffer[hdrLength:n]), time.Now(), nil
|
||||
}
|
||||
|
||||
func (s *BsdSocket) deinitialize() error {
|
||||
return s.bpf.Close()
|
||||
}
|
43
vendor/github.com/j-keck/arping/arping_linux.go
generated
vendored
43
vendor/github.com/j-keck/arping/arping_linux.go
generated
vendored
@ -1,43 +0,0 @@
|
||||
package arping
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
type LinuxSocket struct {
|
||||
sock int
|
||||
toSockaddr syscall.SockaddrLinklayer
|
||||
}
|
||||
|
||||
func initialize(iface net.Interface) (s *LinuxSocket, err error) {
|
||||
s = &LinuxSocket{}
|
||||
s.toSockaddr = syscall.SockaddrLinklayer{Ifindex: iface.Index}
|
||||
|
||||
// 1544 = htons(ETH_P_ARP)
|
||||
const proto = 1544
|
||||
s.sock, err = syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, proto)
|
||||
return s, err
|
||||
}
|
||||
|
||||
func (s *LinuxSocket) send(request arpDatagram) (time.Time, error) {
|
||||
return time.Now(), syscall.Sendto(s.sock, request.MarshalWithEthernetHeader(), 0, &s.toSockaddr)
|
||||
}
|
||||
|
||||
func (s *LinuxSocket) receive() (arpDatagram, time.Time, error) {
|
||||
buffer := make([]byte, 128)
|
||||
socketTimeout := timeout.Nanoseconds() * 2
|
||||
t := syscall.NsecToTimeval(socketTimeout)
|
||||
syscall.SetsockoptTimeval(s.sock, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &t)
|
||||
n, _, err := syscall.Recvfrom(s.sock, buffer, 0)
|
||||
if err != nil {
|
||||
return arpDatagram{}, time.Now(), err
|
||||
}
|
||||
// skip 14 bytes ethernet header
|
||||
return parseArpDatagram(buffer[14:n]), time.Now(), nil
|
||||
}
|
||||
|
||||
func (s *LinuxSocket) deinitialize() error {
|
||||
return syscall.Close(s.sock)
|
||||
}
|
28
vendor/github.com/j-keck/arping/arping_windows.go
generated
vendored
28
vendor/github.com/j-keck/arping/arping_windows.go
generated
vendored
@ -1,28 +0,0 @@
|
||||
// windows currently not supported.
|
||||
// dummy implementation to prevent compilation errors under windows
|
||||
|
||||
package arping
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
var errWindowsNotSupported = errors.New("arping under windows not supported")
|
||||
|
||||
func initialize(iface net.Interface) error {
|
||||
return errWindowsNotSupported
|
||||
}
|
||||
|
||||
func send(request arpDatagram) (time.Time, error) {
|
||||
return time.Now(), errWindowsNotSupported
|
||||
}
|
||||
|
||||
func receive() (arpDatagram, time.Time, error) {
|
||||
return arpDatagram{}, time.Now(), errWindowsNotSupported
|
||||
}
|
||||
|
||||
func deinitialize() error {
|
||||
return errWindowsNotSupported
|
||||
}
|
3
vendor/github.com/j-keck/arping/go.mod
generated
vendored
3
vendor/github.com/j-keck/arping/go.mod
generated
vendored
@ -1,3 +0,0 @@
|
||||
module github.com/j-keck/arping
|
||||
|
||||
go 1.12
|
64
vendor/github.com/j-keck/arping/netutils.go
generated
vendored
64
vendor/github.com/j-keck/arping/netutils.go
generated
vendored
@ -1,64 +0,0 @@
|
||||
package arping
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
func findIPInNetworkFromIface(dstIP net.IP, iface net.Interface) (net.IP, error) {
|
||||
addrs, err := iface.Addrs()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, a := range addrs {
|
||||
if ipnet, ok := a.(*net.IPNet); ok {
|
||||
if ipnet.Contains(dstIP) {
|
||||
return ipnet.IP, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("iface: '%s' can't reach ip: '%s'", iface.Name, dstIP)
|
||||
}
|
||||
|
||||
func findUsableInterfaceForNetwork(dstIP net.IP) (*net.Interface, error) {
|
||||
ifaces, err := net.Interfaces()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
isDown := func(iface net.Interface) bool {
|
||||
return iface.Flags&1 == 0
|
||||
}
|
||||
|
||||
hasAddressInNetwork := func(iface net.Interface) bool {
|
||||
if _, err := findIPInNetworkFromIface(dstIP, iface); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
verboseLog.Println("search usable interface")
|
||||
logIfaceResult := func(msg string, iface net.Interface) {
|
||||
verboseLog.Printf("%10s: %6s %18s %s", msg, iface.Name, iface.HardwareAddr, iface.Flags)
|
||||
}
|
||||
|
||||
for _, iface := range ifaces {
|
||||
if isDown(iface) {
|
||||
logIfaceResult("DOWN", iface)
|
||||
continue
|
||||
}
|
||||
|
||||
if !hasAddressInNetwork(iface) {
|
||||
logIfaceResult("OTHER NET", iface)
|
||||
continue
|
||||
}
|
||||
|
||||
logIfaceResult("USABLE", iface)
|
||||
return &iface, nil
|
||||
}
|
||||
return nil, errors.New("no usable interface found")
|
||||
}
|
3
vendor/github.com/mattn/go-shellwords/go.mod
generated
vendored
3
vendor/github.com/mattn/go-shellwords/go.mod
generated
vendored
@ -1,3 +0,0 @@
|
||||
module github.com/mattn/go-shellwords
|
||||
|
||||
go 1.13
|
201
vendor/github.com/networkplumbing/go-nft/LICENSE
generated
vendored
Normal file
201
vendor/github.com/networkplumbing/go-nft/LICENSE
generated
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
82
vendor/github.com/networkplumbing/go-nft/nft/chain.go
generated
vendored
Normal file
82
vendor/github.com/networkplumbing/go-nft/nft/chain.go
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* This file is part of the go-nft project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2021 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package nft
|
||||
|
||||
import (
|
||||
"github.com/networkplumbing/go-nft/nft/schema"
|
||||
)
|
||||
|
||||
type ChainType string
|
||||
type ChainHook string
|
||||
type ChainPolicy string
|
||||
|
||||
// Chain Types
|
||||
const (
|
||||
TypeFilter ChainType = schema.TypeFilter
|
||||
TypeNAT ChainType = schema.TypeNAT
|
||||
TypeRoute ChainType = schema.TypeRoute
|
||||
)
|
||||
|
||||
// Chain Hooks
|
||||
const (
|
||||
HookPreRouting ChainHook = schema.HookPreRouting
|
||||
HookInput ChainHook = schema.HookInput
|
||||
HookOutput ChainHook = schema.HookOutput
|
||||
HookForward ChainHook = schema.HookForward
|
||||
HookPostRouting ChainHook = schema.HookPostRouting
|
||||
HookIngress ChainHook = schema.HookIngress
|
||||
)
|
||||
|
||||
// Chain Policies
|
||||
const (
|
||||
PolicyAccept ChainPolicy = schema.PolicyAccept
|
||||
PolicyDrop ChainPolicy = schema.PolicyDrop
|
||||
)
|
||||
|
||||
// NewRegularChain returns a new schema chain structure for a regular chain.
|
||||
func NewRegularChain(table *schema.Table, name string) *schema.Chain {
|
||||
return NewChain(table, name, nil, nil, nil, nil)
|
||||
}
|
||||
|
||||
// NewChain returns a new schema chain structure for a base chain.
|
||||
// For base chains, all arguments are required except the policy.
|
||||
// Missing arguments will cause an error once the config is applied.
|
||||
func NewChain(table *schema.Table, name string, ctype *ChainType, hook *ChainHook, prio *int, policy *ChainPolicy) *schema.Chain {
|
||||
c := &schema.Chain{
|
||||
Family: table.Family,
|
||||
Table: table.Name,
|
||||
Name: name,
|
||||
}
|
||||
|
||||
if ctype != nil {
|
||||
c.Type = string(*ctype)
|
||||
}
|
||||
if hook != nil {
|
||||
c.Hook = string(*hook)
|
||||
}
|
||||
if prio != nil {
|
||||
c.Prio = prio
|
||||
}
|
||||
if policy != nil {
|
||||
c.Policy = string(*policy)
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
45
vendor/github.com/networkplumbing/go-nft/nft/config.go
generated
vendored
Normal file
45
vendor/github.com/networkplumbing/go-nft/nft/config.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file is part of the go-nft project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2021 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package nft
|
||||
|
||||
import (
|
||||
nftconfig "github.com/networkplumbing/go-nft/nft/config"
|
||||
nftexec "github.com/networkplumbing/go-nft/nft/exec"
|
||||
)
|
||||
|
||||
type Config = nftconfig.Config
|
||||
|
||||
// NewConfig returns a new nftables config structure.
|
||||
func NewConfig() *nftconfig.Config {
|
||||
return nftconfig.New()
|
||||
}
|
||||
|
||||
// ReadConfig loads the nftables configuration from the system and
|
||||
// returns it as a nftables config structure.
|
||||
// The system is expected to have the `nft` executable deployed and nftables enabled in the kernel.
|
||||
func ReadConfig() (*Config, error) {
|
||||
return nftexec.ReadConfig()
|
||||
}
|
||||
|
||||
// ApplyConfig applies the given nftables config on the system.
|
||||
// The system is expected to have the `nft` executable deployed and nftables enabled in the kernel.
|
||||
func ApplyConfig(c *Config) error {
|
||||
return nftexec.ApplyConfig(c)
|
||||
}
|
80
vendor/github.com/networkplumbing/go-nft/nft/config/chain.go
generated
vendored
Normal file
80
vendor/github.com/networkplumbing/go-nft/nft/config/chain.go
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This file is part of the go-nft project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2021 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/networkplumbing/go-nft/nft/schema"
|
||||
)
|
||||
|
||||
// AddChain appends the given chain to the nftable config.
|
||||
// The chain is added without an explicit action (`add`).
|
||||
// Adding multiple times the same chain has no affect when the config is applied.
|
||||
func (c *Config) AddChain(chain *schema.Chain) {
|
||||
nftable := schema.Nftable{Chain: chain}
|
||||
c.Nftables = append(c.Nftables, nftable)
|
||||
}
|
||||
|
||||
// DeleteChain appends a given chain to the nftable config
|
||||
// with the `delete` action.
|
||||
// Attempting to delete a non-existing chain, results with a failure when the config is applied.
|
||||
// The chain must not contain any rules or be used as a jump target.
|
||||
func (c *Config) DeleteChain(chain *schema.Chain) {
|
||||
nftable := schema.Nftable{Delete: &schema.Objects{Chain: chain}}
|
||||
c.Nftables = append(c.Nftables, nftable)
|
||||
}
|
||||
|
||||
// FlushChain appends a given chain to the nftable config
|
||||
// with the `flush` action.
|
||||
// All rules under the chain are removed (when applied).
|
||||
// Attempting to flush a non-existing chain, results with a failure when the config is applied.
|
||||
func (c *Config) FlushChain(chain *schema.Chain) {
|
||||
nftable := schema.Nftable{Flush: &schema.Objects{Chain: chain}}
|
||||
c.Nftables = append(c.Nftables, nftable)
|
||||
}
|
||||
|
||||
// LookupChain searches the configuration for a matching chain and returns it.
|
||||
// The chain is matched first by the table and chain name.
|
||||
// Other matching fields are optional (for matching base chains).
|
||||
// Mutating the returned chain will result in mutating the configuration.
|
||||
func (c *Config) LookupChain(toFind *schema.Chain) *schema.Chain {
|
||||
for _, nftable := range c.Nftables {
|
||||
if chain := nftable.Chain; chain != nil {
|
||||
match := chain.Table == toFind.Table && chain.Family == toFind.Family && chain.Name == toFind.Name
|
||||
if match {
|
||||
if t := toFind.Type; t != "" {
|
||||
match = match && chain.Type == t
|
||||
}
|
||||
if h := toFind.Hook; h != "" {
|
||||
match = match && chain.Hook == h
|
||||
}
|
||||
if p := toFind.Prio; p != nil {
|
||||
match = match && chain.Prio != nil && *chain.Prio == *p
|
||||
}
|
||||
if p := toFind.Policy; p != "" {
|
||||
match = match && chain.Policy == p
|
||||
}
|
||||
if match {
|
||||
return chain
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
59
vendor/github.com/networkplumbing/go-nft/nft/config/config.go
generated
vendored
Normal file
59
vendor/github.com/networkplumbing/go-nft/nft/config/config.go
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This file is part of the go-nft project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2021 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/networkplumbing/go-nft/nft/schema"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
schema.Root
|
||||
}
|
||||
|
||||
// New returns a new nftables config structure.
|
||||
func New() *Config {
|
||||
c := &Config{}
|
||||
c.Nftables = []schema.Nftable{}
|
||||
return c
|
||||
}
|
||||
|
||||
// ToJSON returns the JSON encoding of the nftables config.
|
||||
func (c *Config) ToJSON() ([]byte, error) {
|
||||
return json.Marshal(*c)
|
||||
}
|
||||
|
||||
// FromJSON decodes the provided JSON-encoded data and populates the nftables config.
|
||||
func (c *Config) FromJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, c); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// FlushRuleset adds a command to the nftables config that erases all the configuration when applied.
|
||||
// It is commonly used as the first config instruction, followed by a declarative configuration.
|
||||
// When used, any previous configuration is flushed away before adding the new one.
|
||||
// Calling FlushRuleset updates the configuration and will take effect only
|
||||
// when applied on the system.
|
||||
func (c *Config) FlushRuleset() {
|
||||
c.Nftables = append(c.Nftables, schema.Nftable{Flush: &schema.Objects{Ruleset: true}})
|
||||
}
|
94
vendor/github.com/networkplumbing/go-nft/nft/config/rule.go
generated
vendored
Normal file
94
vendor/github.com/networkplumbing/go-nft/nft/config/rule.go
generated
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of the go-nft project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2021 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/networkplumbing/go-nft/nft/schema"
|
||||
)
|
||||
|
||||
// AddRule appends the given rule to the nftable config.
|
||||
// The rule is added without an explicit action (`add`).
|
||||
// Adding multiple times the same rule will result in multiple identical rules when applied.
|
||||
func (c *Config) AddRule(rule *schema.Rule) {
|
||||
nftable := schema.Nftable{Rule: rule}
|
||||
c.Nftables = append(c.Nftables, nftable)
|
||||
}
|
||||
|
||||
// DeleteRule appends a given rule to the nftable config
|
||||
// with the `delete` action.
|
||||
// A rule is identified by its handle ID and it must be present in the given rule.
|
||||
// Attempting to delete a non-existing rule, results with a failure when the config is applied.
|
||||
// A common usage is to use LookupRule() and then to pass the result to DeleteRule.
|
||||
func (c *Config) DeleteRule(rule *schema.Rule) {
|
||||
nftable := schema.Nftable{Delete: &schema.Objects{Rule: rule}}
|
||||
c.Nftables = append(c.Nftables, nftable)
|
||||
}
|
||||
|
||||
// LookupRule searches the configuration for a matching rule and returns it.
|
||||
// The rule is matched first by the table and chain.
|
||||
// Other matching fields are optional (nil or an empty string arguments imply no-matching).
|
||||
// Mutating the returned chain will result in mutating the configuration.
|
||||
func (c *Config) LookupRule(toFind *schema.Rule) []*schema.Rule {
|
||||
var rules []*schema.Rule
|
||||
|
||||
for _, nftable := range c.Nftables {
|
||||
if r := nftable.Rule; r != nil {
|
||||
match := r.Table == toFind.Table && r.Family == toFind.Family && r.Chain == toFind.Chain
|
||||
if match {
|
||||
if h := toFind.Handle; h != nil {
|
||||
match = match && r.Handle != nil && *r.Handle == *h
|
||||
}
|
||||
if i := toFind.Index; i != nil {
|
||||
match = match && r.Index != nil && *r.Index == *i
|
||||
}
|
||||
if co := toFind.Comment; co != "" {
|
||||
match = match && r.Comment == co
|
||||
}
|
||||
if toFindStatements := toFind.Expr; toFindStatements != nil {
|
||||
if match = match && len(toFindStatements) == len(r.Expr); match {
|
||||
for i, toFindStatement := range toFindStatements {
|
||||
equal, err := areStatementsEqual(toFindStatement, r.Expr[i])
|
||||
match = match && err == nil && equal
|
||||
}
|
||||
}
|
||||
}
|
||||
if match {
|
||||
rules = append(rules, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rules
|
||||
}
|
||||
|
||||
func areStatementsEqual(statementA, statementB schema.Statement) (bool, error) {
|
||||
statementARow, err := json.Marshal(statementA)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
statementBRow, err := json.Marshal(statementB)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return bytes.Equal(statementARow, statementBRow), nil
|
||||
}
|
63
vendor/github.com/networkplumbing/go-nft/nft/config/table.go
generated
vendored
Normal file
63
vendor/github.com/networkplumbing/go-nft/nft/config/table.go
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* This file is part of the go-nft project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2021 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/networkplumbing/go-nft/nft/schema"
|
||||
)
|
||||
|
||||
// AddTable appends the given table to the nftable config.
|
||||
// The table is added without an explicit action (`add`).
|
||||
// Adding multiple times the same table has no effect when the config is applied.
|
||||
func (c *Config) AddTable(table *schema.Table) {
|
||||
nftable := schema.Nftable{Table: table}
|
||||
c.Nftables = append(c.Nftables, nftable)
|
||||
}
|
||||
|
||||
// DeleteTable appends a given table to the nftable config
|
||||
// with the `delete` action.
|
||||
// Attempting to delete a non-existing table, results with a failure when the config is applied.
|
||||
// All chains and rules under the table are removed as well (when applied).
|
||||
func (c *Config) DeleteTable(table *schema.Table) {
|
||||
nftable := schema.Nftable{Delete: &schema.Objects{Table: table}}
|
||||
c.Nftables = append(c.Nftables, nftable)
|
||||
}
|
||||
|
||||
// FlushTable appends a given table to the nftable config
|
||||
// with the `flush` action.
|
||||
// All chains and rules under the table are removed (when applied).
|
||||
// Attempting to flush a non-existing table, results with a failure when the config is applied.
|
||||
func (c *Config) FlushTable(table *schema.Table) {
|
||||
nftable := schema.Nftable{Flush: &schema.Objects{Table: table}}
|
||||
c.Nftables = append(c.Nftables, nftable)
|
||||
}
|
||||
|
||||
// LookupTable searches the configuration for a matching table and returns it.
|
||||
// Mutating the returned table will result in mutating the configuration.
|
||||
func (c *Config) LookupTable(toFind *schema.Table) *schema.Table {
|
||||
for _, nftable := range c.Nftables {
|
||||
if t := nftable.Table; t != nil {
|
||||
if t.Name == toFind.Name && t.Family == toFind.Family {
|
||||
return t
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
48
vendor/github.com/networkplumbing/go-nft/nft/doc.go
generated
vendored
Normal file
48
vendor/github.com/networkplumbing/go-nft/nft/doc.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* This file is part of the go-nft project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2021 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
// Package nft provides a GO API to nftables.
|
||||
// Together with the schema package, it allows to build, read and apply
|
||||
// nftables configuration on a supporting system.
|
||||
//
|
||||
// The schema structures are based on libnftables-json (https://www.mankier.com/5/libnftables-json)
|
||||
// and implement a subset of them.
|
||||
//
|
||||
// To create a new configuration, use `NewConfig` followed by methods
|
||||
// which populates the configuration with tables, chains and rules, accompanied
|
||||
// to specific actions (add, delete, flush).
|
||||
//
|
||||
// config := nft.NewConfig()
|
||||
// table := nft.NewTable("mytable", nft.FamilyIP)
|
||||
// config.AddTable(table)
|
||||
// chain := nft.NewRegularChain(table, "mychain")
|
||||
// config.AddChain(chain)
|
||||
// rule := nft.NewRule(table, chain, statements, nil, nil, "mycomment")
|
||||
//
|
||||
// To apply a configuration on the system, use the `ApplyConfig` function.
|
||||
// err := nft.ApplyConfig(config)
|
||||
//
|
||||
// To read the configuration from the system, use the `ReadConfig` function.
|
||||
// config, err := nft.ReadConfig()
|
||||
//
|
||||
// For full setup example, see the integration test: tests/config_test.go
|
||||
//
|
||||
// The nft package is dependent on the `nft` binary and the kernel nftables
|
||||
// support.
|
||||
package nft
|
102
vendor/github.com/networkplumbing/go-nft/nft/exec/exec.go
generated
vendored
Normal file
102
vendor/github.com/networkplumbing/go-nft/nft/exec/exec.go
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* This file is part of the go-nft project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2021 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package exec
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
nftconfig "github.com/networkplumbing/go-nft/nft/config"
|
||||
)
|
||||
|
||||
const (
|
||||
cmdBin = "nft"
|
||||
cmdFile = "-f"
|
||||
cmdJSON = "-j"
|
||||
cmdList = "list"
|
||||
cmdRuleset = "ruleset"
|
||||
)
|
||||
|
||||
// ReadConfig loads the nftables configuration from the system and
|
||||
// returns it as a nftables config structure.
|
||||
// The system is expected to have the `nft` executable deployed and nftables enabled in the kernel.
|
||||
func ReadConfig() (*nftconfig.Config, error) {
|
||||
stdout, err := execCommand(cmdJSON, cmdList, cmdRuleset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config := nftconfig.New()
|
||||
if err := config.FromJSON(stdout.Bytes()); err != nil {
|
||||
return nil, fmt.Errorf("failed to list ruleset: %v", err)
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// ApplyConfig applies the given nftables config on the system.
|
||||
// The system is expected to have the `nft` executable deployed and nftables enabled in the kernel.
|
||||
func ApplyConfig(c *nftconfig.Config) error {
|
||||
data, err := c.ToJSON()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tmpFile, err := ioutil.TempFile(os.TempDir(), "spoofcheck-")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create temporary file: %v", err)
|
||||
}
|
||||
defer os.Remove(tmpFile.Name())
|
||||
|
||||
if _, err = tmpFile.Write(data); err != nil {
|
||||
return fmt.Errorf("failed to write to temporary file: %v", err)
|
||||
}
|
||||
|
||||
if err := tmpFile.Close(); err != nil {
|
||||
return fmt.Errorf("failed to close temporary file: %v", err)
|
||||
}
|
||||
|
||||
if _, err := execCommand(cmdJSON, cmdFile, tmpFile.Name()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func execCommand(args ...string) (*bytes.Buffer, error) {
|
||||
cmd := exec.Command(cmdBin, args...)
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stderr = &stderr
|
||||
cmd.Stdout = &stdout
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"failed to execute %s %s: %v stdout:'%s' stderr:'%s'",
|
||||
cmd.Path, strings.Join(cmd.Args, " "), err, stdout.String(), stderr.String(),
|
||||
)
|
||||
}
|
||||
|
||||
return &stdout, nil
|
||||
}
|
58
vendor/github.com/networkplumbing/go-nft/nft/rule.go
generated
vendored
Normal file
58
vendor/github.com/networkplumbing/go-nft/nft/rule.go
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This file is part of the go-nft project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2021 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package nft
|
||||
|
||||
import (
|
||||
"github.com/networkplumbing/go-nft/nft/schema"
|
||||
)
|
||||
|
||||
// NewRule returns a new schema rule structure.
|
||||
func NewRule(table *schema.Table, chain *schema.Chain, expr []schema.Statement, handle *int, index *int, comment string) *schema.Rule {
|
||||
c := &schema.Rule{
|
||||
Family: table.Family,
|
||||
Table: table.Name,
|
||||
Chain: chain.Name,
|
||||
Expr: expr,
|
||||
Handle: handle,
|
||||
Index: index,
|
||||
Comment: comment,
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
type RuleIndex int
|
||||
|
||||
// NewRuleIndex returns a rule index object which acts as an iterator.
|
||||
// When multiple rules are added to a chain, index allows to define an order between them.
|
||||
// The first rule which is added to a chain should have no index (it is assigned index 0),
|
||||
// following rules should have the index set, referencing after/before which rule the new one is to be added/inserted.
|
||||
func NewRuleIndex() *RuleIndex {
|
||||
var index RuleIndex = -1
|
||||
return &index
|
||||
}
|
||||
|
||||
// Next returns the next iteration value as an integer pointer.
|
||||
// When first time called, it returns the value 0.
|
||||
func (i *RuleIndex) Next() *int {
|
||||
*i++
|
||||
var index = int(*i)
|
||||
return &index
|
||||
}
|
53
vendor/github.com/networkplumbing/go-nft/nft/schema/chain.go
generated
vendored
Normal file
53
vendor/github.com/networkplumbing/go-nft/nft/schema/chain.go
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This file is part of the go-nft project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2021 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package schema
|
||||
|
||||
// Chain Types
|
||||
const (
|
||||
TypeFilter = "filter"
|
||||
TypeNAT = "nat"
|
||||
TypeRoute = "route"
|
||||
)
|
||||
|
||||
// Chain Hooks
|
||||
const (
|
||||
HookPreRouting = "prerouting"
|
||||
HookInput = "input"
|
||||
HookOutput = "output"
|
||||
HookForward = "forward"
|
||||
HookPostRouting = "postrouting"
|
||||
HookIngress = "ingress"
|
||||
)
|
||||
|
||||
// Chain Policies
|
||||
const (
|
||||
PolicyAccept = "accept"
|
||||
PolicyDrop = "drop"
|
||||
)
|
||||
|
||||
type Chain struct {
|
||||
Family string `json:"family"`
|
||||
Table string `json:"table"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Hook string `json:"hook,omitempty"`
|
||||
Prio *int `json:"prio,omitempty"`
|
||||
Policy string `json:"policy,omitempty"`
|
||||
}
|
366
vendor/github.com/networkplumbing/go-nft/nft/schema/rule.go
generated
vendored
Normal file
366
vendor/github.com/networkplumbing/go-nft/nft/schema/rule.go
generated
vendored
Normal file
@ -0,0 +1,366 @@
|
||||
/*
|
||||
* This file is part of the go-nft project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2021 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package schema
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Rule struct {
|
||||
Family string `json:"family"`
|
||||
Table string `json:"table"`
|
||||
Chain string `json:"chain"`
|
||||
Expr []Statement `json:"expr,omitempty"`
|
||||
Handle *int `json:"handle,omitempty"`
|
||||
Index *int `json:"index,omitempty"`
|
||||
Comment string `json:"comment,omitempty"`
|
||||
}
|
||||
|
||||
type Statement struct {
|
||||
Counter *Counter `json:"counter,omitempty"`
|
||||
Match *Match `json:"match,omitempty"`
|
||||
Verdict
|
||||
Nat
|
||||
}
|
||||
|
||||
type Counter struct {
|
||||
Packets int `json:"packets"`
|
||||
Bytes int `json:"bytes"`
|
||||
}
|
||||
|
||||
type Nat struct {
|
||||
Snat *Snat `json:"snat,omitempty"`
|
||||
Dnat *Dnat `json:"dnat,omitempty"`
|
||||
Masquerade *Masquerade `json:"masquerade,omitempty"`
|
||||
Redirect *Redirect `json:"redirect,omitempty"`
|
||||
}
|
||||
|
||||
type Snat struct {
|
||||
Addr *Expression `json:"addr,omitempty"`
|
||||
Family *string `json:"family,omitempty"`
|
||||
Port *Expression `json:"port,omitempty"`
|
||||
Flags *Flags `json:"flags,omitempty"`
|
||||
}
|
||||
|
||||
type Dnat struct {
|
||||
Addr *Expression `json:"addr,omitempty"`
|
||||
Family *string `json:"family,omitempty"`
|
||||
Port *Expression `json:"port,omitempty"`
|
||||
Flags *Flags `json:"flags,omitempty"`
|
||||
}
|
||||
|
||||
const masquerade = "masquerade"
|
||||
|
||||
type Masquerade struct {
|
||||
Enabled bool `json:"-"`
|
||||
Port *Expression `json:"port,omitempty"`
|
||||
Flags *Flags `json:"flags,omitempty"`
|
||||
}
|
||||
|
||||
const redirect = "redirect"
|
||||
|
||||
type Redirect struct {
|
||||
Enabled bool `json:"-"`
|
||||
Port *Expression `json:"port,omitempty"`
|
||||
Flags *Flags `json:"flags,omitempty"`
|
||||
}
|
||||
|
||||
type Flags struct {
|
||||
Flags []string `json:"-"`
|
||||
}
|
||||
|
||||
// NAT Flags
|
||||
const (
|
||||
NATFlagRandom = "random"
|
||||
NATFlagFullyRandom = "fully-random"
|
||||
NATFlagPersistent = "persistent"
|
||||
)
|
||||
|
||||
type Verdict struct {
|
||||
SimpleVerdict
|
||||
Jump *ToTarget `json:"jump,omitempty"`
|
||||
Goto *ToTarget `json:"goto,omitempty"`
|
||||
}
|
||||
|
||||
type SimpleVerdict struct {
|
||||
Accept bool `json:"-"`
|
||||
Continue bool `json:"-"`
|
||||
Drop bool `json:"-"`
|
||||
Return bool `json:"-"`
|
||||
}
|
||||
|
||||
type ToTarget struct {
|
||||
Target string `json:"target"`
|
||||
}
|
||||
|
||||
type Match struct {
|
||||
Op string `json:"op"`
|
||||
Left Expression `json:"left"`
|
||||
Right Expression `json:"right"`
|
||||
}
|
||||
|
||||
type Expression struct {
|
||||
String *string `json:"-"`
|
||||
Bool *bool `json:"-"`
|
||||
Float64 *float64 `json:"-"`
|
||||
Payload *Payload `json:"payload,omitempty"`
|
||||
// RowData accepts arbitrary data which cannot be composed from the existing schema.
|
||||
// Use `json.RawMessage()` or `[]byte()` for the value.
|
||||
// Example:
|
||||
// `schema.Expression{RowData: json.RawMessage(`{"meta":{"key":"iifname"}}`)}`
|
||||
RowData json.RawMessage `json:"-"`
|
||||
}
|
||||
|
||||
type Payload struct {
|
||||
Protocol string `json:"protocol"`
|
||||
Field string `json:"field"`
|
||||
}
|
||||
|
||||
// Verdict Operations
|
||||
const (
|
||||
VerdictAccept = "accept"
|
||||
VerdictContinue = "continue"
|
||||
VerdictDrop = "drop"
|
||||
VerdictReturn = "return"
|
||||
)
|
||||
|
||||
// Match Operators
|
||||
const (
|
||||
OperAND = "&" // Binary AND
|
||||
OperOR = "|" // Binary OR
|
||||
OperXOR = "^" // Binary XOR
|
||||
OperLSH = "<<" // Left shift
|
||||
OperRSH = ">>" // Right shift
|
||||
OperEQ = "==" // Equal
|
||||
OperNEQ = "!=" // Not equal
|
||||
OperLS = "<" // Less than
|
||||
OperGR = ">" // Greater than
|
||||
OperLSE = "<=" // Less than or equal to
|
||||
OperGRE = ">=" // Greater than or equal to
|
||||
OperIN = "in" // Perform a lookup, i.e. test if bits on RHS are contained in LHS value
|
||||
)
|
||||
|
||||
// Payload Expressions
|
||||
const (
|
||||
PayloadKey = "payload"
|
||||
// Ethernet
|
||||
PayloadProtocolEther = "ether"
|
||||
PayloadFieldEtherDAddr = "daddr"
|
||||
PayloadFieldEtherSAddr = "saddr"
|
||||
PayloadFieldEtherType = "type"
|
||||
|
||||
// IP (common)
|
||||
PayloadFieldIPVer = "version"
|
||||
PayloadFieldIPDscp = "dscp"
|
||||
PayloadFieldIPEcn = "ecn"
|
||||
PayloadFieldIPLen = "length"
|
||||
PayloadFieldIPSAddr = "saddr"
|
||||
PayloadFieldIPDAddr = "daddr"
|
||||
|
||||
// IPv4
|
||||
PayloadProtocolIP4 = "ip"
|
||||
PayloadFieldIP4HdrLen = "hdrlength"
|
||||
PayloadFieldIP4Id = "id"
|
||||
PayloadFieldIP4FragOff = "frag-off"
|
||||
PayloadFieldIP4Ttl = "ttl"
|
||||
PayloadFieldIP4Protocol = "protocol"
|
||||
PayloadFieldIP4Chksum = "checksum"
|
||||
|
||||
// IPv6
|
||||
PayloadProtocolIP6 = "ip6"
|
||||
PayloadFieldIP6FlowLabel = "flowlabel"
|
||||
PayloadFieldIP6NextHdr = "nexthdr"
|
||||
PayloadFieldIP6HopLimit = "hoplimit"
|
||||
)
|
||||
|
||||
func (s Statement) MarshalJSON() ([]byte, error) {
|
||||
type _Statement Statement
|
||||
statement := _Statement(s)
|
||||
|
||||
// Convert to a dynamic structure
|
||||
data, err := json.Marshal(statement)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dynamicStructure := make(map[string]json.RawMessage)
|
||||
if err := json.Unmarshal(data, &dynamicStructure); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch {
|
||||
case s.Accept:
|
||||
dynamicStructure[VerdictAccept] = nil
|
||||
case s.Continue:
|
||||
dynamicStructure[VerdictContinue] = nil
|
||||
case s.Drop:
|
||||
dynamicStructure[VerdictDrop] = nil
|
||||
case s.Return:
|
||||
dynamicStructure[VerdictReturn] = nil
|
||||
case s.Masquerade != nil && s.Masquerade.Enabled && s.Masquerade.Port == nil && s.Masquerade.Flags == nil:
|
||||
dynamicStructure[masquerade] = nil
|
||||
case s.Redirect != nil && s.Redirect.Enabled && s.Redirect.Port == nil && s.Redirect.Flags == nil:
|
||||
dynamicStructure[redirect] = nil
|
||||
}
|
||||
|
||||
data, err = json.Marshal(dynamicStructure)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (s *Statement) UnmarshalJSON(data []byte) error {
|
||||
type _Statement Statement
|
||||
statement := _Statement{}
|
||||
|
||||
if err := json.Unmarshal(data, &statement); err != nil {
|
||||
return err
|
||||
}
|
||||
*s = Statement(statement)
|
||||
|
||||
dynamicStructure := make(map[string]json.RawMessage)
|
||||
if err := json.Unmarshal(data, &dynamicStructure); err != nil {
|
||||
return err
|
||||
}
|
||||
_, s.Accept = dynamicStructure[VerdictAccept]
|
||||
_, s.Continue = dynamicStructure[VerdictContinue]
|
||||
_, s.Drop = dynamicStructure[VerdictDrop]
|
||||
_, s.Return = dynamicStructure[VerdictReturn]
|
||||
|
||||
if _, masqueradeDefined := dynamicStructure[masquerade]; s.Masquerade == nil && masqueradeDefined {
|
||||
s.Masquerade = &Masquerade{Enabled: true}
|
||||
}
|
||||
|
||||
if _, redirectDefined := dynamicStructure[redirect]; s.Redirect == nil && redirectDefined {
|
||||
s.Redirect = &Redirect{Enabled: true}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e Expression) MarshalJSON() ([]byte, error) {
|
||||
var dynamicStruct interface{}
|
||||
|
||||
switch {
|
||||
case e.RowData != nil:
|
||||
return e.RowData, nil
|
||||
case e.String != nil:
|
||||
dynamicStruct = *e.String
|
||||
case e.Float64 != nil:
|
||||
dynamicStruct = *e.Float64
|
||||
case e.Bool != nil:
|
||||
dynamicStruct = *e.Bool
|
||||
default:
|
||||
type _Expression Expression
|
||||
dynamicStruct = _Expression(e)
|
||||
}
|
||||
|
||||
return json.Marshal(dynamicStruct)
|
||||
}
|
||||
|
||||
func (e *Expression) UnmarshalJSON(data []byte) error {
|
||||
var dynamicStruct interface{}
|
||||
if err := json.Unmarshal(data, &dynamicStruct); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch dynamicStruct.(type) {
|
||||
case string:
|
||||
d := dynamicStruct.(string)
|
||||
e.String = &d
|
||||
case float64:
|
||||
d := dynamicStruct.(float64)
|
||||
e.Float64 = &d
|
||||
case bool:
|
||||
d := dynamicStruct.(bool)
|
||||
e.Bool = &d
|
||||
case []interface{}:
|
||||
e.RowData = data
|
||||
case map[string]interface{}:
|
||||
type _Expression Expression
|
||||
expression := _Expression(*e)
|
||||
if err := json.Unmarshal(data, &expression); err != nil {
|
||||
return err
|
||||
}
|
||||
*e = Expression(expression)
|
||||
default:
|
||||
return fmt.Errorf("unsupported field type in expression: %T(%v)", dynamicStruct, dynamicStruct)
|
||||
}
|
||||
|
||||
if e.String == nil && e.Float64 == nil && e.Bool == nil && e.Payload == nil {
|
||||
e.RowData = data
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f Flags) MarshalJSON() ([]byte, error) {
|
||||
var dynamicStruct interface{}
|
||||
|
||||
switch flagCount := len(f.Flags); {
|
||||
case flagCount == 1:
|
||||
dynamicStruct = f.Flags[0]
|
||||
case flagCount > 1:
|
||||
dynamicStruct = f.Flags
|
||||
}
|
||||
|
||||
return json.Marshal(dynamicStruct)
|
||||
}
|
||||
|
||||
func (f *Flags) UnmarshalJSON(data []byte) error {
|
||||
var dynamicStruct interface{}
|
||||
if err := json.Unmarshal(data, &dynamicStruct); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch v := dynamicStruct.(type) {
|
||||
case string:
|
||||
f.Flags = []string{v}
|
||||
case []interface{}:
|
||||
for _, val := range v {
|
||||
stringVal, ok := val.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("flags values require string type: %T(%v)", dynamicStruct, dynamicStruct)
|
||||
}
|
||||
f.Flags = append(f.Flags, stringVal)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("flags values require string type: %T(%v)", dynamicStruct, dynamicStruct)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Accept() Verdict {
|
||||
return Verdict{SimpleVerdict: SimpleVerdict{Accept: true}}
|
||||
}
|
||||
|
||||
func Continue() Verdict {
|
||||
return Verdict{SimpleVerdict: SimpleVerdict{Continue: true}}
|
||||
}
|
||||
|
||||
func Drop() Verdict {
|
||||
return Verdict{SimpleVerdict: SimpleVerdict{Drop: true}}
|
||||
}
|
||||
|
||||
func Return() Verdict {
|
||||
return Verdict{SimpleVerdict: SimpleVerdict{Return: true}}
|
||||
}
|
80
vendor/github.com/networkplumbing/go-nft/nft/schema/schema.go
generated
vendored
Normal file
80
vendor/github.com/networkplumbing/go-nft/nft/schema/schema.go
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This file is part of the go-nft project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2021 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package schema
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
type Root struct {
|
||||
Nftables []Nftable `json:"nftables"`
|
||||
}
|
||||
|
||||
const ruleSetKey = "ruleset"
|
||||
|
||||
type Objects struct {
|
||||
Table *Table `json:"table,omitempty"`
|
||||
Chain *Chain `json:"chain,omitempty"`
|
||||
Rule *Rule `json:"rule,omitempty"`
|
||||
Ruleset bool `json:"-"`
|
||||
}
|
||||
|
||||
func (o Objects) MarshalJSON() ([]byte, error) {
|
||||
type _Objects Objects
|
||||
objects := _Objects(o)
|
||||
|
||||
data, err := json.Marshal(objects)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if o.Ruleset {
|
||||
// Convert to a dynamic structure
|
||||
var dynamicStructure map[string]json.RawMessage
|
||||
if err := json.Unmarshal(data, &dynamicStructure); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dynamicStructure[ruleSetKey] = nil
|
||||
data, err = json.Marshal(dynamicStructure)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
type Nftable struct {
|
||||
Table *Table `json:"table,omitempty"`
|
||||
Chain *Chain `json:"chain,omitempty"`
|
||||
Rule *Rule `json:"rule,omitempty"`
|
||||
|
||||
Add *Objects `json:"add,omitempty"`
|
||||
Delete *Objects `json:"delete,omitempty"`
|
||||
Flush *Objects `json:"flush,omitempty"`
|
||||
|
||||
Metainfo *Metainfo `json:"metainfo,omitempty"`
|
||||
}
|
||||
|
||||
type Metainfo struct {
|
||||
Version string `json:"version"`
|
||||
ReleaseName string `json:"release_name"`
|
||||
JsonSchemaVersion int `json:"json_schema_version"`
|
||||
}
|
35
vendor/github.com/networkplumbing/go-nft/nft/schema/table.go
generated
vendored
Normal file
35
vendor/github.com/networkplumbing/go-nft/nft/schema/table.go
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of the go-nft project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2021 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package schema
|
||||
|
||||
// Table Address Families
|
||||
const (
|
||||
FamilyIP = "ip" // IPv4 address AddressFamily.
|
||||
FamilyIP6 = "ip6" // IPv6 address AddressFamily.
|
||||
FamilyINET = "inet" // Internet (IPv4/IPv6) address AddressFamily.
|
||||
FamilyARP = "arp" // ARP address AddressFamily, handling IPv4 ARP packets.
|
||||
FamilyBridge = "bridge" // Bridge address AddressFamily, handling packets which traverse a bridge device.
|
||||
FamilyNETDEV = "netdev" // Netdev address AddressFamily, handling packets from ingress.
|
||||
)
|
||||
|
||||
type Table struct {
|
||||
Family string `json:"family"`
|
||||
Name string `json:"name"`
|
||||
}
|
51
vendor/github.com/networkplumbing/go-nft/nft/table.go
generated
vendored
Normal file
51
vendor/github.com/networkplumbing/go-nft/nft/table.go
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* This file is part of the go-nft project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2021 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
package nft
|
||||
|
||||
import "github.com/networkplumbing/go-nft/nft/schema"
|
||||
|
||||
type AddressFamily string
|
||||
|
||||
// Address Families
|
||||
const (
|
||||
FamilyIP AddressFamily = schema.FamilyIP
|
||||
FamilyIP6 AddressFamily = schema.FamilyIP6
|
||||
FamilyINET AddressFamily = schema.FamilyINET
|
||||
FamilyARP AddressFamily = schema.FamilyARP
|
||||
FamilyBridge AddressFamily = schema.FamilyBridge
|
||||
FamilyNETDEV AddressFamily = schema.FamilyNETDEV
|
||||
)
|
||||
|
||||
type TableAction string
|
||||
|
||||
// Table Actions
|
||||
const (
|
||||
TableADD TableAction = "add"
|
||||
TableDELETE TableAction = "delete"
|
||||
TableFLUSH TableAction = "flush"
|
||||
)
|
||||
|
||||
// NewTable returns a new schema table structure.
|
||||
func NewTable(name string, family AddressFamily) *schema.Table {
|
||||
return &schema.Table{
|
||||
Name: name,
|
||||
Family: string(family),
|
||||
}
|
||||
}
|
8
vendor/github.com/nxadm/tail/go.mod
generated
vendored
8
vendor/github.com/nxadm/tail/go.mod
generated
vendored
@ -1,8 +0,0 @@
|
||||
module github.com/nxadm/tail
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7
|
||||
)
|
6
vendor/github.com/nxadm/tail/go.sum
generated
vendored
6
vendor/github.com/nxadm/tail/go.sum
generated
vendored
@ -1,6 +0,0 @@
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
13
vendor/github.com/onsi/ginkgo/go.mod
generated
vendored
13
vendor/github.com/onsi/ginkgo/go.mod
generated
vendored
@ -1,13 +0,0 @@
|
||||
module github.com/onsi/ginkgo
|
||||
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0
|
||||
github.com/nxadm/tail v1.4.8
|
||||
github.com/onsi/gomega v1.10.1
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e
|
||||
)
|
||||
|
||||
retract v1.16.3 // git tag accidentally associated with incorrect git commit
|
86
vendor/github.com/onsi/ginkgo/go.sum
generated
vendored
86
vendor/github.com/onsi/ginkgo/go.sum
generated
vendored
@ -1,86 +0,0 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
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=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
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 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
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/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
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/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091 h1:DMyOG0U+gKfu8JZzg2UQe9MeaC1X+xQWlAKcRnjxjCw=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e h1:4nW4NLDYnU28ojHaHO8OVxFHk/aQ33U01a9cjED+pzE=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
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=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
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=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
10
vendor/github.com/onsi/gomega/go.mod
generated
vendored
10
vendor/github.com/onsi/gomega/go.mod
generated
vendored
@ -1,10 +0,0 @@
|
||||
module github.com/onsi/gomega
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/onsi/ginkgo v1.16.4
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
95
vendor/github.com/onsi/gomega/go.sum
generated
vendored
95
vendor/github.com/onsi/gomega/go.sum
generated
vendored
@ -1,95 +0,0 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
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=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
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/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.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
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/onsi/ginkgo v1.6.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.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
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/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e h1:4nW4NLDYnU28ojHaHO8OVxFHk/aQ33U01a9cjED+pzE=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
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=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
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=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
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=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
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=
|
10
vendor/github.com/sirupsen/logrus/go.mod
generated
vendored
10
vendor/github.com/sirupsen/logrus/go.mod
generated
vendored
@ -1,10 +0,0 @@
|
||||
module github.com/sirupsen/logrus
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/testify v1.2.2
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037
|
||||
)
|
||||
|
||||
go 1.13
|
8
vendor/github.com/sirupsen/logrus/go.sum
generated
vendored
8
vendor/github.com/sirupsen/logrus/go.sum
generated
vendored
@ -1,8 +0,0 @@
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
8
vendor/github.com/vishvananda/netlink/go.mod
generated
vendored
8
vendor/github.com/vishvananda/netlink/go.mod
generated
vendored
@ -1,8 +0,0 @@
|
||||
module github.com/vishvananda/netlink
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae
|
||||
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1
|
||||
)
|
6
vendor/github.com/vishvananda/netlink/go.sum
generated
vendored
6
vendor/github.com/vishvananda/netlink/go.sum
generated
vendored
@ -1,6 +0,0 @@
|
||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae h1:4hwBBUfQCFe3Cym0ZtKyq7L16eZUtYKs+BaHDN6mAns=
|
||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867 h1:JoRuNIf+rpHl+VhScRQQvzbHed86tKkqwPMV34T8myw=
|
||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1 h1:sIky/MyNRSHTrdxfsiUSS4WIAMvInbeXljJz+jDjeYE=
|
||||
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
5
vendor/github.com/vishvananda/netns/go.mod
generated
vendored
5
vendor/github.com/vishvananda/netns/go.mod
generated
vendored
@ -1,5 +0,0 @@
|
||||
module github.com/vishvananda/netns
|
||||
|
||||
go 1.12
|
||||
|
||||
require golang.org/x/sys v0.0.0-20200217220822-9197077df867
|
2
vendor/github.com/vishvananda/netns/go.sum
generated
vendored
2
vendor/github.com/vishvananda/netns/go.sum
generated
vendored
@ -1,2 +0,0 @@
|
||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867 h1:JoRuNIf+rpHl+VhScRQQvzbHed86tKkqwPMV34T8myw=
|
||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
15
vendor/go.opencensus.io/go.mod
generated
vendored
15
vendor/go.opencensus.io/go.mod
generated
vendored
@ -1,15 +0,0 @@
|
||||
module go.opencensus.io
|
||||
|
||||
require (
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6
|
||||
github.com/golang/protobuf v1.3.1
|
||||
github.com/google/go-cmp v0.3.0
|
||||
github.com/stretchr/testify v1.4.0
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd // indirect
|
||||
golang.org/x/text v0.3.2 // indirect
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb // indirect
|
||||
google.golang.org/grpc v1.20.1
|
||||
)
|
||||
|
||||
go 1.13
|
74
vendor/go.opencensus.io/go.sum
generated
vendored
74
vendor/go.opencensus.io/go.sum
generated
vendored
@ -1,74 +0,0 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd h1:r7DufRZuZbWB7j439YfAzP8RPDa9unLkpwQKUYbIMPI=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-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-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd h1:/e+gpKk9r3dJobndpTytxS2gOy6m5uvpg+ISQoEcusQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
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/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb h1:i1Ppqkc3WQXikh8bXiwHqAN5Rv3/qDCcRk0/Otx73BY=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
|
||||
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
5
vendor/gopkg.in/yaml.v2/go.mod
generated
vendored
5
vendor/gopkg.in/yaml.v2/go.mod
generated
vendored
@ -1,5 +0,0 @@
|
||||
module gopkg.in/yaml.v2
|
||||
|
||||
go 1.15
|
||||
|
||||
require gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
|
49
vendor/modules.txt
vendored
49
vendor/modules.txt
vendored
@ -1,10 +1,11 @@
|
||||
# github.com/Microsoft/go-winio v0.4.17
|
||||
## explicit; go 1.12
|
||||
github.com/Microsoft/go-winio
|
||||
github.com/Microsoft/go-winio/pkg/guid
|
||||
github.com/Microsoft/go-winio/pkg/security
|
||||
github.com/Microsoft/go-winio/vhd
|
||||
# github.com/Microsoft/hcsshim v0.8.20
|
||||
## explicit
|
||||
## explicit; go 1.13
|
||||
github.com/Microsoft/hcsshim
|
||||
github.com/Microsoft/hcsshim/computestorage
|
||||
github.com/Microsoft/hcsshim/hcn
|
||||
@ -30,15 +31,16 @@ github.com/Microsoft/hcsshim/internal/wclayer
|
||||
github.com/Microsoft/hcsshim/internal/winapi
|
||||
github.com/Microsoft/hcsshim/osversion
|
||||
# github.com/alexflint/go-filemutex v1.1.0
|
||||
## explicit
|
||||
## explicit; go 1.13
|
||||
github.com/alexflint/go-filemutex
|
||||
# github.com/buger/jsonparser v1.1.1
|
||||
## explicit
|
||||
## explicit; go 1.13
|
||||
github.com/buger/jsonparser
|
||||
# github.com/containerd/cgroups v1.0.1
|
||||
## explicit; go 1.13
|
||||
github.com/containerd/cgroups/stats/v1
|
||||
# github.com/containernetworking/cni v1.0.1
|
||||
## explicit
|
||||
## explicit; go 1.14
|
||||
github.com/containernetworking/cni/libcni
|
||||
github.com/containernetworking/cni/pkg/invoke
|
||||
github.com/containernetworking/cni/pkg/skel
|
||||
@ -51,10 +53,10 @@ github.com/containernetworking/cni/pkg/types/internal
|
||||
github.com/containernetworking/cni/pkg/utils
|
||||
github.com/containernetworking/cni/pkg/version
|
||||
# github.com/coreos/go-iptables v0.6.0
|
||||
## explicit
|
||||
## explicit; go 1.16
|
||||
github.com/coreos/go-iptables/iptables
|
||||
# github.com/coreos/go-systemd/v22 v22.3.2
|
||||
## explicit
|
||||
## explicit; go 1.12
|
||||
github.com/coreos/go-systemd/v22/activation
|
||||
# github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c
|
||||
## explicit
|
||||
@ -68,30 +70,37 @@ github.com/d2g/dhcp4server
|
||||
github.com/d2g/dhcp4server/leasepool
|
||||
github.com/d2g/dhcp4server/leasepool/memorypool
|
||||
# github.com/fsnotify/fsnotify v1.4.9
|
||||
## explicit; go 1.13
|
||||
github.com/fsnotify/fsnotify
|
||||
# github.com/godbus/dbus/v5 v5.0.4
|
||||
## explicit
|
||||
## explicit; go 1.12
|
||||
github.com/godbus/dbus/v5
|
||||
# github.com/gogo/protobuf v1.3.2
|
||||
## explicit; go 1.15
|
||||
github.com/gogo/protobuf/gogoproto
|
||||
github.com/gogo/protobuf/proto
|
||||
github.com/gogo/protobuf/protoc-gen-gogo/descriptor
|
||||
# github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e
|
||||
## explicit
|
||||
github.com/golang/groupcache/lru
|
||||
# github.com/j-keck/arping v1.0.2
|
||||
## explicit
|
||||
github.com/j-keck/arping
|
||||
# github.com/mattn/go-shellwords v1.0.12
|
||||
## explicit
|
||||
## explicit; go 1.13
|
||||
github.com/mattn/go-shellwords
|
||||
# github.com/networkplumbing/go-nft v0.2.0
|
||||
## explicit; go 1.16
|
||||
github.com/networkplumbing/go-nft/nft
|
||||
github.com/networkplumbing/go-nft/nft/config
|
||||
github.com/networkplumbing/go-nft/nft/exec
|
||||
github.com/networkplumbing/go-nft/nft/schema
|
||||
# github.com/nxadm/tail v1.4.8
|
||||
## explicit; go 1.13
|
||||
github.com/nxadm/tail
|
||||
github.com/nxadm/tail/ratelimiter
|
||||
github.com/nxadm/tail/util
|
||||
github.com/nxadm/tail/watch
|
||||
github.com/nxadm/tail/winfile
|
||||
# github.com/onsi/ginkgo v1.16.4
|
||||
## explicit
|
||||
## explicit; go 1.15
|
||||
github.com/onsi/ginkgo
|
||||
github.com/onsi/ginkgo/config
|
||||
github.com/onsi/ginkgo/extensions/table
|
||||
@ -114,7 +123,7 @@ github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable
|
||||
github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty
|
||||
github.com/onsi/ginkgo/types
|
||||
# github.com/onsi/gomega v1.15.0
|
||||
## explicit
|
||||
## explicit; go 1.14
|
||||
github.com/onsi/gomega
|
||||
github.com/onsi/gomega/format
|
||||
github.com/onsi/gomega/gbytes
|
||||
@ -127,27 +136,30 @@ github.com/onsi/gomega/matchers/support/goraph/node
|
||||
github.com/onsi/gomega/matchers/support/goraph/util
|
||||
github.com/onsi/gomega/types
|
||||
# github.com/pkg/errors v0.9.1
|
||||
## explicit
|
||||
github.com/pkg/errors
|
||||
# github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1
|
||||
## explicit
|
||||
github.com/safchain/ethtool
|
||||
# github.com/sirupsen/logrus v1.8.1
|
||||
## explicit
|
||||
## explicit; go 1.13
|
||||
github.com/sirupsen/logrus
|
||||
# github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5
|
||||
## explicit
|
||||
## explicit; go 1.12
|
||||
github.com/vishvananda/netlink
|
||||
github.com/vishvananda/netlink/nl
|
||||
# github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f
|
||||
## explicit
|
||||
## explicit; go 1.12
|
||||
github.com/vishvananda/netns
|
||||
# go.opencensus.io v0.22.3
|
||||
## explicit; go 1.13
|
||||
go.opencensus.io
|
||||
go.opencensus.io/internal
|
||||
go.opencensus.io/trace
|
||||
go.opencensus.io/trace/internal
|
||||
go.opencensus.io/trace/tracestate
|
||||
# golang.org/x/net v0.0.0-20210428140749-89ef3d95e781
|
||||
## explicit; go 1.11
|
||||
golang.org/x/net/bpf
|
||||
golang.org/x/net/html
|
||||
golang.org/x/net/html/atom
|
||||
@ -156,12 +168,13 @@ golang.org/x/net/internal/iana
|
||||
golang.org/x/net/internal/socket
|
||||
golang.org/x/net/ipv4
|
||||
# golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e
|
||||
## explicit
|
||||
## explicit; go 1.17
|
||||
golang.org/x/sys/internal/unsafeheader
|
||||
golang.org/x/sys/unix
|
||||
golang.org/x/sys/windows
|
||||
golang.org/x/sys/windows/registry
|
||||
# golang.org/x/text v0.3.6
|
||||
## explicit; go 1.11
|
||||
golang.org/x/text/encoding
|
||||
golang.org/x/text/encoding/charmap
|
||||
golang.org/x/text/encoding/htmlindex
|
||||
@ -180,6 +193,8 @@ golang.org/x/text/language
|
||||
golang.org/x/text/runes
|
||||
golang.org/x/text/transform
|
||||
# gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7
|
||||
## explicit
|
||||
gopkg.in/tomb.v1
|
||||
# gopkg.in/yaml.v2 v2.4.0
|
||||
## explicit; go 1.15
|
||||
gopkg.in/yaml.v2
|
||||
|
Reference in New Issue
Block a user