From de0a125a7c4faf54e0bc7b42c4837aa2ccad642e Mon Sep 17 00:00:00 2001 From: mbonchevaxway <61872876+mbonchevaxway@users.noreply.github.com> Date: Tue, 26 Jan 2021 17:03:33 +0200 Subject: [PATCH 01/76] Initial commit --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..daf7de5 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# agents-kong \ No newline at end of file From c5881f51d88ce7aabbba39f55cb5047c0776c899 Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Tue, 26 Jan 2021 15:06:07 -0700 Subject: [PATCH 02/76] set up for discovery and traceability --- .gitignore | 3 + .idea/agents-kong.iml | 9 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + .idea/watcherTasks.xml | 9 + .idea/workspace.xml | 81 +++ Makefile | 11 + cmd/main.go | 9 + default_apic_discovery_agent.yml | 14 + default_apic_traceability_agent.yml | 46 ++ go.mod | 45 ++ go.sum | 905 ++++++++++++++++++++++++ pkg/beater/custom_log_filebeater.go | 97 +++ pkg/cmd/discovery/discoveryCmd.go | 62 ++ pkg/cmd/root.go | 27 + pkg/cmd/traceability/traceabilityCmd.go | 70 ++ pkg/config/discovery/config.go | 31 + pkg/config/traceability/config.go | 32 + pkg/gateway/client.go | 88 +++ pkg/gateway/definitions.go | 28 + pkg/gateway/eventmapper.go | 123 ++++ pkg/gateway/eventprocessor.go | 93 +++ pkg/gateway/logreader.go | 32 + 23 files changed, 1829 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/agents-kong.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/watcherTasks.xml create mode 100644 .idea/workspace.xml create mode 100644 Makefile create mode 100644 cmd/main.go create mode 100644 default_apic_discovery_agent.yml create mode 100644 default_apic_traceability_agent.yml create mode 100644 go.mod create mode 100644 go.sum create mode 100644 pkg/beater/custom_log_filebeater.go create mode 100644 pkg/cmd/discovery/discoveryCmd.go create mode 100644 pkg/cmd/root.go create mode 100644 pkg/cmd/traceability/traceabilityCmd.go create mode 100644 pkg/config/discovery/config.go create mode 100644 pkg/config/traceability/config.go create mode 100644 pkg/gateway/client.go create mode 100644 pkg/gateway/definitions.go create mode 100644 pkg/gateway/eventmapper.go create mode 100644 pkg/gateway/eventprocessor.go create mode 100644 pkg/gateway/logreader.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8ddb00d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.env +apic_discovery_agent.yml +apic_traceability_agent.yml \ No newline at end of file diff --git a/.idea/agents-kong.iml b/.idea/agents-kong.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/agents-kong.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..24dc88f --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/watcherTasks.xml b/.idea/watcherTasks.xml new file mode 100644 index 0000000..27aa2e8 --- /dev/null +++ b/.idea/watcherTasks.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..bc52b61 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1611686013581 + + + + + + + + + + true + + \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e4dd4f6 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +GO_VERSION=1.14.3 + +PROJECT_NAME := agents-kong + +export GOPRIVATE=git.ecd.axway.org/apigov + +tidy: go.mod + @go mod tidy + +download: tidy + @go mod download \ No newline at end of file diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 0000000..da026db --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,9 @@ +package main + +import ( + "github.com/Axway/agents-kong/pkg/cmd" +) + +func main() { + cmd.Execute() +} diff --git a/default_apic_discovery_agent.yml b/default_apic_discovery_agent.yml new file mode 100644 index 0000000..f6d102d --- /dev/null +++ b/default_apic_discovery_agent.yml @@ -0,0 +1,14 @@ +# this is a sample config file. Copy the content of this file to a new file named apic_discovery_agent.yml +central: + organizationID: "" + environment: + auth: + clientID: + privateKey: + publicKey: + +gateway-section: + specPath: ./apis/musical_instruments.json + config_key_1: value + config_key_2: value + config_key_3: value diff --git a/default_apic_traceability_agent.yml b/default_apic_traceability_agent.yml new file mode 100644 index 0000000..999e374 --- /dev/null +++ b/default_apic_traceability_agent.yml @@ -0,0 +1,46 @@ +# this is a sample config file. Copy the content of this file to a new file named apic_traceability_agent.yml +apic_traceability_agent: + central: + organizationID: "" + environment: + auth: + clientID: + privateKey: + publicKey: + + gateway-section: + logFile: ./logs/traffic.log + processOnInput: false + config_key_1: "value-1" + config_key_3: "value-2" + config_key_2: "value-3" + +# Condor Ingestion service +output.traceability: + enabled: true + hosts: + - ${TRACEABILITY_HOST:"ingestion-lumberjack.datasearch.axway.com:453"} + protocol: ${TRACEABILITY_PROTOCOL:"tcp"} + compression_level: ${TRACEABILITY_COMPRESSIONLEVEL:3} + ssl: + enabled: true + verification_mode: none + cipher_suites: + - "ECDHE-ECDSA-AES-128-GCM-SHA256" + - "ECDHE-ECDSA-AES-256-GCM-SHA384" + - "ECDHE-ECDSA-CHACHA20-POLY1305" + - "ECDHE-RSA-AES-128-CBC-SHA256" + - "ECDHE-RSA-AES-128-GCM-SHA256" + - "ECDHE-RSA-AES-256-GCM-SHA384" + - "ECDHE-RSA-CHACHA20-POLY1205" + worker: 1 + pipelining: 0 + proxy_url: ${TRACEABILITY_PROXYURL:""} + +logging: + metrics: + enabled: false + # Send all logging output to stderr + to_stderr: true + # Set log level + level: ${LOG_LEVEL:"info"} \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5706245 --- /dev/null +++ b/go.mod @@ -0,0 +1,45 @@ +module github.com/Axway/agents-kong + +go 1.13 + +require ( + github.com/Axway/agent-sdk v0.0.19-0.20210126163226-3d297ae76e96 + github.com/Shopify/sarama v1.26.4 // indirect + github.com/docker/docker v1.13.1 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect + github.com/eapache/go-resiliency v1.2.0 // indirect + github.com/elastic/beats/v7 v7.7.1 + github.com/garyburd/redigo v1.6.0 // indirect + github.com/googleapis/gnostic v0.3.1 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hpcloud/tail v1.0.0 + github.com/imdario/mergo v0.3.9 // indirect + github.com/jcmturner/gofork v1.0.0 // indirect + github.com/klauspost/cpuid v1.3.1 // indirect + github.com/kr/pretty v0.2.0 // indirect + github.com/miekg/dns v1.1.29 // indirect + github.com/mitchellh/hashstructure v1.0.0 // indirect + github.com/pelletier/go-toml v1.8.0 // indirect + github.com/pierrec/lz4 v2.5.2+incompatible // indirect + github.com/spf13/afero v1.3.0 // indirect + github.com/spf13/cast v1.3.1 // indirect + github.com/spf13/cobra v1.0.0 + gopkg.in/ini.v1 v1.57.0 // indirect + gopkg.in/jcmturner/gokrb5.v7 v7.5.0 // indirect +) + +replace ( + github.com/Azure/go-autorest => github.com/Azure/go-autorest v12.2.0+incompatible + github.com/Shopify/sarama => github.com/elastic/sarama v0.0.0-20191122160421-355d120d0970 + github.com/docker/docker => github.com/docker/engine v17.12.0-ce-rc1.0.20190717161051-705d9623b7c1+incompatible + github.com/docker/go-plugins-helpers => github.com/elastic/go-plugins-helpers v0.0.0-20200207104224-bdf17607b79f + github.com/dop251/goja => github.com/andrewkroh/goja v0.0.0-20190128172624-dd2ac4456e20 + github.com/fsnotify/fsevents => github.com/elastic/fsevents v0.0.0-20181029231046-e1d381a4d270 + github.com/fsnotify/fsnotify => github.com/adriansr/fsnotify v0.0.0-20180417234312-c9bbe1f46f1d + github.com/google/gopacket => github.com/adriansr/gopacket v1.1.18-0.20200327165309-dd62abfa8a41 + github.com/insomniacslk/dhcp => github.com/elastic/dhcp v0.0.0-20200227161230-57ec251c7eb3 // indirect + github.com/tonistiigi/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c + k8s.io/api => k8s.io/api v0.17.0 + k8s.io/apimachinery => k8s.io/apimachinery v0.17.0 + k8s.io/client-go => k8s.io/client-go v0.17.0 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..db7a881 --- /dev/null +++ b/go.sum @@ -0,0 +1,905 @@ +4d63.com/embedfiles v0.0.0-20190311033909-995e0740726f/go.mod h1:HxEsUxoVZyRxsZML/S6e2xAuieFMlGO0756ncWx1aXE= +4d63.com/tz v1.1.1-0.20191124060701-6d37baae851b/go.mod h1:SHGqVdL7hd2ZaX2T9uEiOZ/OFAUfCCLURdLPJsd8ZNs= +bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +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.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +code.cloudfoundry.org/go-diodes v0.0.0-20190809170250-f77fb823c7ee/go.mod h1:Jzi+ccHgo/V/PLQUaQ6hnZcC1c4BS790gx21LRRui4g= +code.cloudfoundry.org/go-loggregator v7.4.0+incompatible/go.mod h1:KPBTRqj+y738Nhf1+g4JHFaBU8j7dedirR5ETNHvMXU= +code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:sk5LnIjB/nIEU7yP5sDQExVm62wu0pBh3yrElngUisI= +code.cloudfoundry.org/rfc5424 v0.0.0-20180905210152-236a6d29298a/go.mod h1:tkZo8GtzBjySJ7USvxm4E36lNQw1D3xM6oKHGqdaAJ4= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Axway/agent-sdk v0.0.19-0.20210126163226-3d297ae76e96 h1:w99KVTrHHFFT8f9Ej0OcnPAKyWITMCxjfV4DsU2IfKA= +github.com/Axway/agent-sdk v0.0.19-0.20210126163226-3d297ae76e96/go.mod h1:fOaWmFFg1eDheNJZNe2+T/jRwfSm8AWcap1p+ytBv8I= +github.com/Azure/azure-amqp-common-go/v3 v3.0.0/go.mod h1:SY08giD/XbhTz07tJdpw1SoxQXHPN30+DI3Z04SYqyg= +github.com/Azure/azure-event-hubs-go/v3 v3.1.2/go.mod h1:hR40byNJjKkS74+3RhloPQ8sJ8zFQeJ920Uk3oYY0+k= +github.com/Azure/azure-pipeline-go v0.1.8/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg= +github.com/Azure/azure-pipeline-go v0.1.9/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg= +github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= +github.com/Azure/azure-sdk-for-go v37.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-storage-blob-go v0.6.0/go.mod h1:oGfmITT1V6x//CswqY2gtAHND+xIP64/qL7a5QJix0Y= +github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= +github.com/Azure/go-amqp v0.12.6/go.mod h1:qApuH6OFTSKZFmCOxccvAv5rLizBQf4v8pRmG138DPo= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= +github.com/Azure/go-autorest/autorest v0.9.4/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= +github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM= +github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= +github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +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/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA= +github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= +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.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/StackExchange/wmi v0.0.0-20170221213301-9f32b5905fd6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/adriansr/fsnotify v0.0.0-20180417234312-c9bbe1f46f1d h1:g0M6kedfjDpyAAuxqBvJzMNjFzlrQ7Av6LCDFqWierk= +github.com/adriansr/fsnotify v0.0.0-20180417234312-c9bbe1f46f1d/go.mod h1:VykaKG/ofkKje+MSvqjrDsz1wfyHIvEVFljhq2EOZ4g= +github.com/adriansr/gopacket v1.1.18-0.20200327165309-dd62abfa8a41/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= +github.com/aerospike/aerospike-client-go v1.27.1-0.20170612174108-0f3b54da6bdc/go.mod h1:zj8LBEnWBDOVEIJt8LvaRvDG5ARAoa5dBeHaB472NRc= +github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= +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/andrewkroh/goja v0.0.0-20190128172624-dd2ac4456e20 h1:7rj9qZ63knnVo2ZeepYHvHuRdG76f3tRUTdIQDzRBeI= +github.com/andrewkroh/goja v0.0.0-20190128172624-dd2ac4456e20/go.mod h1:cI59GRkC2FRaFYtgbYEqMlgnnfvAwXzjojyZKXwklNg= +github.com/andrewkroh/sys v0.0.0-20151128191922-287798fe3e43/go.mod h1:tJPYQG4mnMeUtQvQKNkbsFrnmZOg59Qnf8CcctFv5v4= +github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/aws/aws-lambda-go v1.6.0/go.mod h1:zUsUQhAUjYzR8AuduJPCfhBuKWUaDbQiPOG+ouzmE1A= +github.com/aws/aws-sdk-go-v2 v0.9.0/go.mod h1:sa1GePZ/LfBGI4dSq30f6uR4Tthll8axxtEPvlpXZ8U= +github.com/awslabs/goformation/v3 v3.1.0/go.mod h1:hQ5RXo3GNm2laHWKizDzU5DsDy+yNcenSca2UxN0850= +github.com/awslabs/goformation/v4 v4.1.0/go.mod h1:MBDN7u1lMNDoehbFuO4uPvgwPeolTMA2TzX1yO6KlxI= +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/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= +github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/bradleyfalzon/ghinstallation v1.1.0/go.mod h1:p7iD8KytOOKg2wCqbwvJlq4JGpYMjwjkiqdyUqOIHLI= +github.com/bsm/sarama-cluster v2.1.14-0.20180625083203-7e67d87a6b3f+incompatible/go.mod h1:r7ao+4tTNXvWm+VRpRJchr2kQhqxgmAp2iEX5W96gMM= +github.com/cavaliercoder/badio v0.0.0-20160213150051-ce5280129e9e/go.mod h1:V284PjgVwSk4ETmz84rpu9ehpGg7swlIH8npP9k2bGw= +github.com/cavaliercoder/go-rpm v0.0.0-20190131055624-7a9c54e3d83e/go.mod h1:AZIh1CCnMrcVm6afFf96PBvE2MRpWFco91z8ObJtgDY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudfoundry-community/go-cfclient v0.0.0-20190808214049-35bcce23fc5f/go.mod h1:RtIewdO+K/czvxvIFCMbPyx7jdxSLL1RZ+DA/Vk8Lwg= +github.com/cloudfoundry/sonde-go v0.0.0-20171206171820-b33733203bb4/go.mod h1:GS0pCHd7onIsewbw8Ue9qa9pZPv2V88cUZDttK6KzgI= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= +github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= +github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY= +github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= +github.com/coreos/bbolt v1.3.1-coreos.6.0.20180318001526-af9db2027c98/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +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/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +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-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/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/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/davecgh/go-xdr v0.0.0-20161123171359-e6a2ba005892/go.mod h1:CTDl0pzVzE5DEzZhPfvhY/9sPFMQIxaJ9VAMs9AagrE= +github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc= +github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= +github.com/devigned/tab v0.1.2-0.20190607222403-0c15cf42f9a2/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgrijalva/jwt-go v3.2.1-0.20190620180102-5e25c22bd5d6+incompatible h1:4jGdduO4ceTJFKf0IhgaB8NJapGqKHwC2b4xQ/cXujM= +github.com/dgrijalva/jwt-go v3.2.1-0.20190620180102-5e25c22bd5d6+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/digitalocean/go-libvirt v0.0.0-20180301200012-6075ea3c39a1/go.mod h1:PRcPVAAma6zcLpFd4GZrjR/MRpood3TamjKI2m/z/Uw= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dlclark/regexp2 v1.1.7-0.20171009020623-7632a260cbaf h1:uOWCk+L8abzw0BzmnCn7j7VT3g6bv9zW8fkR0yOP0Q4= +github.com/dlclark/regexp2 v1.1.7-0.20171009020623-7632a260cbaf/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/engine v17.12.0-ce-rc1.0.20190717161051-705d9623b7c1+incompatible h1:4Pnn+RsurVEiBbmqlRtzh77HLMiP4NaaqRHOOK4aPj8= +github.com/docker/engine v17.12.0-ce-rc1.0.20190717161051-705d9623b7c1+incompatible/go.mod h1:3CPr2caMgTHxxIAZgEMd3uLYPDlRvPqCpyeRf6ncPcY= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= +github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +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/dop251/goja_nodejs v0.0.0-20171011081505-adff31b136e6 h1:RrkoB0pT3gnjXhL/t10BSP1mcr/0Ldea2uMyuBr2SWk= +github.com/dop251/goja_nodejs v0.0.0-20171011081505-adff31b136e6/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q= +github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/eclipse/paho.mqtt.golang v1.2.1-0.20200121105743-0d940dd29fd2/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= +github.com/elastic/beats/v7 v7.7.1 h1:aets27tEojy9IbpCW/X3CxlzObVjtMKyLpGk9RtXYNM= +github.com/elastic/beats/v7 v7.7.1/go.mod h1:6wQ39q838+pC8Y927cbdfRWFnoOvni1+CTorV4lgpYA= +github.com/elastic/dhcp v0.0.0-20200227161230-57ec251c7eb3/go.mod h1:aPqzac6AYkipvp4hufTyMj5PDIphF3+At8zr7r51xjY= +github.com/elastic/ecs v1.5.0 h1:/VEIBsRU4ecq2+U3RPfKNc6bFyomP6qnthYEcQZu8GU= +github.com/elastic/ecs v1.5.0/go.mod h1:pgiLbQsijLOJvFR8OTILLu0Ni/R/foUNg0L+T6mU9b4= +github.com/elastic/fsevents v0.0.0-20181029231046-e1d381a4d270/go.mod h1:Msl1pdboCbArMF/nSCDUXgQuWTeoMmE/z8607X+k7ng= +github.com/elastic/go-libaudit v0.4.0/go.mod h1:lNJ7gX+arohEQTwqinAc8xycVuFNqsaunba1mwcBdvE= +github.com/elastic/go-licenser v0.2.1/go.mod h1:D8eNQk70FOCVBl3smCGQt/lv7meBeQno2eI1S5apiHQ= +github.com/elastic/go-lookslike v0.3.0/go.mod h1:AhH+rdJux5RlVjs+6ej4jkvYyoNRkj2crxmqeHlj3hA= +github.com/elastic/go-lumber v0.1.0 h1:HUjpyg36v2HoKtXlEC53EJ3zDFiDRn65d7B8dBHNius= +github.com/elastic/go-lumber v0.1.0/go.mod h1:8YvjMIRYypWuPvpxx7WoijBYdbB7XIh/9FqSYQZTtxQ= +github.com/elastic/go-perf v0.0.0-20191212140718-9c656876f595/go.mod h1:s09U1b4P1ZxnKx2OsqY7KlHdCesqZWIhyq0Gs/QC/Us= +github.com/elastic/go-plugins-helpers v0.0.0-20200207104224-bdf17607b79f/go.mod h1:OPGqFNdTS34kMReS5hPFtBhD9J8itmSDurs1ix2wx7c= +github.com/elastic/go-seccomp-bpf v1.1.0 h1:jUzzDc6LyCtdolZdvL/26dad6rZ9vsc7xZ2eadKECAU= +github.com/elastic/go-seccomp-bpf v1.1.0/go.mod h1:l+89Vy5BzjVcaX8USZRMOwmwwDScE+vxCFzzvQwN7T8= +github.com/elastic/go-structform v0.0.6 h1:wqeK4LwD2NNDOoRGTImE24S6pkCDVr8+oUSIkmChzLk= +github.com/elastic/go-structform v0.0.6/go.mod h1:QrMyP3oM9Sjk92EVGLgRaL2lKt0Qx7ZNDRWDxB6khVs= +github.com/elastic/go-sysinfo v1.3.0 h1:eb2XFGTMlSwG/yyU9Y8jVAYLIzU2sFzWXwo2gmetyrE= +github.com/elastic/go-sysinfo v1.3.0/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= +github.com/elastic/go-txfile v0.0.7 h1:Yn28gclW7X0Qy09nSMSsx0uOAvAGMsp6XHydbiLVe2s= +github.com/elastic/go-txfile v0.0.7/go.mod h1:H0nCoFae0a4ga57apgxFsgmRjevNCsEaT6g56JoeKAE= +github.com/elastic/go-ucfg v0.7.0/go.mod h1:iaiY0NBIYeasNgycLyTvhJftQlQEUO2hpF+FX0JKxzo= +github.com/elastic/go-ucfg v0.8.3 h1:leywnFjzr2QneZZWhE6uWd+QN/UpP0sdJRHYyuFvkeo= +github.com/elastic/go-ucfg v0.8.3/go.mod h1:iaiY0NBIYeasNgycLyTvhJftQlQEUO2hpF+FX0JKxzo= +github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU= +github.com/elastic/go-windows v1.0.1 h1:AlYZOldA+UJ0/2nBuqWdo90GFCgG9xuyw9SYzGUtJm0= +github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss= +github.com/elastic/gosigar v0.10.5 h1:GzPQ+78RaAb4J63unidA/JavQRKrB6s8IOzN6Ib59jo= +github.com/elastic/gosigar v0.10.5/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= +github.com/elastic/sarama v0.0.0-20191122160421-355d120d0970 h1:rSo6gsz4zOanqtJ5fmZYQJvEJnA5YsVOB25casIwqUw= +github.com/elastic/sarama v0.0.0-20191122160421-355d120d0970/go.mod h1:fGP8eQ6PugKEI0iUETYYtnP6d1pH/bdDMTel1X5ajsU= +github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= +github.com/emersion/go-smtp v0.13.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/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.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fatih/color v1.5.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.4.1 h1:Wv2VwvNn73pAdFIVUQRXYDFp31lXKbqblIXo/Q5GPSg= +github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= +github.com/garyburd/redigo v1.0.1-0.20160525165706-b8dc90050f24/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc= +github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/getkin/kin-openapi v0.9.0 h1:/vaUQkiOR+vfFO3oilZentZTfAhz7OzXPhLdNas4q4w= +github.com/getkin/kin-openapi v0.9.0/go.mod h1:zZQMFkVgRHCdhgb6ihCTIo9dyDZFvX0k/xAKqw1FhPw= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +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-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-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/go-ole/go-ole v1.2.5-0.20190920104607-14974a1cf647/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-sourcemap/sourcemap v2.1.2+incompatible h1:0b/xya7BKGhXuqFESKM4oIiRo9WOt2ebz7KxfreD6ug= +github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gocarina/gocsv v0.0.0-20170324095351-ffef3ffc77be/go.mod h1:/oj50ZdPq/cUjA02lMZhijk5kR31SEydKyqah1OgBuo= +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/godror/godror v0.10.4/go.mod h1:9MVLtu25FBJBMHkPs0m3Ngf/VmwGcLpM2HS8PlNGw9U= +github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/flock v0.7.2-0.20190320160742-5135e617513b h1:3QNh5Xo2pmr2nZXENtnztfpjej8XY8EPmvYxF5SzY9M= +github.com/gofrs/flock v0.7.2-0.20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +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.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +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 h1:5ZkaAPbicIKTF2I64qf5Fh8Aa83Q/dnOafMYV0OMwjA= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/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/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +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/flatbuffers v1.7.2-0.20170925184458-7a6b2bf521e9/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +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 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= +github.com/google/go-github/v29 v29.0.2/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/gofuzz v1.0.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/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2-0.20190416172445-c2e93f3ae59f/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/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.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.3.1-0.20190624222214-25d8b0b66985/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= +github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= +github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorhill/cronexpr v0.0.0-20161205141322-d520615e531a/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= +github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I= +github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +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-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.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap 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-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +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/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.2-0.20190520140433-59383c442f7d/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hcl v1.0.1-0.20180906183839-65a6292f0157 h1:uyodBE3xDz0ynKs1tLBU26wOQoEkAqqiY18DbZ+FZrA= +github.com/hashicorp/hcl v1.0.1-0.20180906183839-65a6292f0157/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/haya14busa/go-actions-toolkit v0.0.0-20200105081403-ca0307860f01/go.mod h1:1DWDZmeYf0LX30zscWb7K9rUMeirNeBMd5Dum+seUhc= +github.com/haya14busa/go-checkstyle v0.0.0-20170303121022-5e9d09f51fa1/go.mod h1:RsN5RGgVYeXpcXNtWyztD5VIe7VNSEqpJvF2iEH7QvI= +github.com/haya14busa/secretbox v0.0.0-20180525171038-07c7ecf409f5/go.mod h1:FGO/dXIFZnan7KvvUSFk1hYMnoVNzB6NTMPrmke8SSI= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +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.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= +github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= +github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= +github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= +github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE= +github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +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.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= +github.com/json-iterator/go v1.1.8/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 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +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/justinas/nosurf v1.1.0/go.mod h1:ALpWdSbuNGy2lZWtyXdjkYv4edL23oSEgfBT1gPJ5BQ= +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/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.8.2 h1:Bx0qjetmNjdFXASH02NSAREKpiaDwkO1DRZ3dV2KCcs= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s= +github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4= +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 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.2-0.20190507191818-2ff3cb3adc01/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/magefile/mage v1.9.0 h1:t3AU2wNwehMCW97vuqQLtw6puppWXHO+O2MHo5a50XE= +github.com/magefile/mage v1.9.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11/go.mod h1:Ah2dBMoxZEqk118as2T4u4fjfXarE0pPnMJaArZQZsI= +github.com/mattn/go-colorable v0.0.8/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +github.com/mattn/go-ieproxy v0.0.0-20191113090002-7c0f6868bffe/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= +github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-shellwords v1.0.7/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +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/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.29 h1:xHBEhR+t5RzcFJjBLJlax2daXOrTYtr9z4WdKEfWFzg= +github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/gox v1.0.1/go.mod h1:ED6BioOGXMswlXa2zxfh/xdd5QhwYliBFn9V18Ap4z4= +github.com/mitchellh/hashstructure v0.0.0-20170116052023-ab25296c0f51/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= +github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9dGS02Q3Y= +github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg= +github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/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/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.5.0/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/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.2.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +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.20190228220655-ac19fd6e7483 h1:eFd3FsB01m/zNg/yBMYdm/XqiqCztcN9SVRPtGtzDHo= +github.com/opencontainers/go-digest v1.0.0-rc1.0.20190228220655-ac19fd6e7483/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 h1:yN8BPXVwMBAm3Cuvh1L5XE8XpvYRMdsVLd82ILprhUU= +github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +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-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2/go.mod h1:L3UMQOThbttwfYRNFOWLLVXMhk5Lkio4GGOtw5UrxS0= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw= +github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pierrec/lz4 v2.2.6+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= +github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrre/gotestcover v0.0.0-20160113212533-7b94f124d338/go.mod h1:4xpMLz7RBWyB+ElzHu8Llua96TRCB3YwX+l5EP1wmHk= +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/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +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.1.1-0.20190913103102-20428fa0bffc/go.mod h1:ikMPikHu8SMvBGWoKulvvOOZN227amf2E9eMYqyAwAY= +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/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.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.9-0.20191208103036-42f6e295b56f h1:i2BUTcG1g7lSgF/xVL4BJBAdrtNp4zL8woVTGHpEG4g= +github.com/prometheus/procfs v0.0.9-0.20191208103036-42f6e295b56f/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/prometheus v2.5.0+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rakyll/statik v0.1.6/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563 h1:dY6ETXrvDG7Sa4vE8ZQG4yqWg6UnOcbqTAahkV813vQ= +github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/reviewdog/errorformat v0.0.0-20200109134752-8983be9bc7dd/go.mod h1:giYAXnpegRDPsXUO7TRpDKXJo1lFGYxyWRfEt5iQ+OA= +github.com/reviewdog/reviewdog v0.9.17/go.mod h1:Y0yPFDTi9L5ohkoecJdgbvAhq+dUXp+zI7atqVibwKg= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-parser v0.0.0-20130731160455-ca8abbf65d0e/go.mod h1:Sb6li54lXV0yYEjI4wX8cucdQ9gqUJV3+Ngg3l9g30I= +github.com/samuel/go-thrift v0.0.0-20140522043831-2187045faa54/go.mod h1:Vrkh1pnjV9Bl8c3P9zH0/D4NlOHWP5d4/hF4YTULaec= +github.com/sanathkr/go-yaml v0.0.0-20170819195128-ed9d249f429b/go.mod h1:8458kAagoME2+LN5//WxE71ysZ3B7r22fdgb7qVmXSY= +github.com/sanathkr/yaml v0.0.0-20170819201035-0056894fa522/go.mod h1:tQTYKOQgxoH3v6dEmdHiz4JG+nbxWwM5fgPQUpSZqVQ= +github.com/sanathkr/yaml v1.0.1-0.20170819201035-0056894fa522/go.mod h1:tQTYKOQgxoH3v6dEmdHiz4JG+nbxWwM5fgPQUpSZqVQ= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shirou/gopsutil v2.19.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +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.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 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +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/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/snowzach/rotatefilehook v0.0.0-20180327172521-2f64f265f58c h1:iUEy7/LRto3JqR/GLXDTEFP+s+qIjWw4pM8yzMfXC9A= +github.com/snowzach/rotatefilehook v0.0.0-20180327172521-2f64f265f58c/go.mod h1:ZLVe3VfhAuMYLYWliGEydMBoRnfib8EFSqkBYu1ck9E= +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/afero v1.3.0 h1:Ysnmjh1Di8EaWaBv40CYR4IdaIsBc5996Gh1oZzCBKk= +github.com/spf13/afero v1.3.0/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/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 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +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.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= +github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +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.1.2-0.20180702103455-b8b73a35e983 h1:4s04gnPlcop3dmAHjOAHWa6gX7Dg7h0gh81gr3GwzIk= +github.com/stretchr/objx v0.1.2-0.20180702103455-b8b73a35e983/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/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.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/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/tidwall/gjson v1.6.7 h1:Mb1M9HZCRWEcXQ8ieJo7auYyyiSux6w9XN3AdTpxJrE= +github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= +github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE= +github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU= +github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80/go.mod h1:iFyPdL66DjUD96XmzVL3ZntbzcflLnznH0fr99w5VqE= +github.com/tsg/go-daemon v0.0.0-20200207173439-e704b93fd89b/go.mod h1:jAqhj/JBVC1PwcLTWd6rjQyGyItxxrhpiBl8LSuAGmw= +github.com/tsg/gopacket v0.0.0-20190320122513-dd3d0e41124a h1:vVmCas8T0lbxAI1GuQO45L0o/OrWJSXtiK6vH27Qspg= +github.com/tsg/gopacket v0.0.0-20190320122513-dd3d0e41124a/go.mod h1:RIkfovP3Y7my19aXEjjbNd9E5TlHozzAyt7B8AaEcwg= +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/urso/go-bin v0.0.0-20180220135811-781c575c9f0e h1:NiofbjIUI5gR+ybDsGSVH1fWyjSeDYiYVJHT1+kcsak= +github.com/urso/go-bin v0.0.0-20180220135811-781c575c9f0e/go.mod h1:6GfHrdWBQYjFRIznu7XuQH4lYB2w8nO4bnImVKkzPOM= +github.com/urso/magetools v0.0.0-20190919040553-290c89e0c230/go.mod h1:DFxTNgS/ExCGmmjVjSOgS2WjtfjKXgCyDzAFgbtovSA= +github.com/urso/magetools v0.0.0-20200106130147-61080ed7b22b h1:eRYRTx+2CteM4P2U+VgAeAmuMAyB/QAGxWtgH7/o4l8= +github.com/urso/magetools v0.0.0-20200106130147-61080ed7b22b/go.mod h1:DFxTNgS/ExCGmmjVjSOgS2WjtfjKXgCyDzAFgbtovSA= +github.com/urso/qcgen v0.0.0-20180131103024-0b059e7db4f4 h1:hhA8EBThzz9PztawVTycKvfETVuBqxAQ5keFlAVtbAw= +github.com/urso/qcgen v0.0.0-20180131103024-0b059e7db4f4/go.mod h1:RspW+E2Yb7Fs7HclB2tiDaiu6Rp41BiIG4Wo1YaoXGc= +github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g= +github.com/vmware/govmomi v0.0.0-20170802214208-2cad15190b41/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= +github.com/xanzy/go-gitlab v0.22.3/go.mod h1:t4Bmvnxj7k37S4Y17lfLx+nLqkf/oQwT2HagfWKv5Og= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/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/xeipuuv/gojsonschema v0.0.0-20181112162635-ac52e6811b56/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/gopher-lua v0.0.0-20170403160031-b402f3114ec7/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +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.uber.org/atomic v1.3.1/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= +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/multierr v1.1.1-0.20170829224307-fb7d312c2c04 h1:8sYuFs2lovgFwQi15/wIkCkGX9sL8RouzbWUmBjTcXk= +go.uber.org/multierr v1.1.1-0.20170829224307-fb7d312c2c04/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.7.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= +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-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/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-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +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-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +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-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +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-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-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/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/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +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= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181108082009-03003ca0c849/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-20181201002055-351d144fa1fc/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-20190213061140-3a22650c66bd/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/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-20191021144547-ec77196f6094/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191112182307-2180aed22343/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-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/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 h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +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= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/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-20190209173611-3b5209105503/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-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/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-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200102141924-c96a22e43c9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/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 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +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 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/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-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +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-20190621195816-6e04913cbbac/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-20191112195655-aa38f8e97acc/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-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4 h1:Toz2IK7k8rbltAXwNAxKcn9OzqyNfMUhUNjz3sL0NMk= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +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.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb h1:ADPHZzpzM4tk4V4S5cnCrr5SwzvlrPRmqqCuJDB8UTs= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +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-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +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/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= +gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww= +gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw= +gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= +gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM= +gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= +gopkg.in/jcmturner/goidentity.v3 v3.0.0 h1:1duIyWiTaYvVx3YX2CYtpJbUFd7/UuPYCfgXtQ3VTbI= +gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= +gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= +gopkg.in/jcmturner/gokrb5.v7 v7.5.0 h1:a9tsXlIDD9SKxotJMK3niV7rPZAJeX2aD/0yg3qlIrg= +gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= +gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU= +gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= +gopkg.in/mgo.v2 v2.0.0-20160818020120-3f83fa500528/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +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/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.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/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 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c h1:grhR+C34yXImVGp7EzNk+DTIk+323eIUWOmEevy6bDo= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/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= +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= +howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= +howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= +k8s.io/api v0.17.0 h1:H9d/lw+VkZKEVIUc8F3wgiQ+FUXTTr21M87jXLU7yqM= +k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI= +k8s.io/apimachinery v0.17.0 h1:xRBnuie9rXcPxUkDizUsGvPf1cnlZCFu210op7J7LJo= +k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= +k8s.io/client-go v0.17.0 h1:8QOGvUGdqDMFrm9sD6IUFl256BcffynGoe80sxgTEDg= +k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.4-0.20190719014911-6a023d6d0e09/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= +k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= +k8s.io/utils v0.0.0-20190712204705-3dccf664f023/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo= +k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.1.1-0.20190704183835-4cd0c284b15f h1:rBmJnclilUaQG3K5/iL9zD57jtKRimbK2bJQGqktcs8= +sigs.k8s.io/yaml v1.1.1-0.20190704183835-4cd0c284b15f/go.mod h1:JLeFbgenPHTQHNZeYbMLTT18IylpsFnR2+IHPl6wctA= diff --git a/pkg/beater/custom_log_filebeater.go b/pkg/beater/custom_log_filebeater.go new file mode 100644 index 0000000..69a8f39 --- /dev/null +++ b/pkg/beater/custom_log_filebeater.go @@ -0,0 +1,97 @@ +package beater + +import ( + "github.com/Axway/agent-sdk/pkg/traceability" + agenterrors "github.com/Axway/agent-sdk/pkg/util/errors" + hc "github.com/Axway/agent-sdk/pkg/util/healthcheck" + + "github.com/elastic/beats/v7/libbeat/beat" + "github.com/elastic/beats/v7/libbeat/common" + "github.com/elastic/beats/v7/libbeat/logp" + + config "github.com/Axway/agents-kong/pkg/config/traceability" + "github.com/Axway/agents-kong/pkg/gateway" +) + +// customLogBeater configuration. +type customLogBeater struct { + done chan struct{} + logReader *gateway.LogReader + eventProcessor *gateway.EventProcessor + client beat.Client + eventChannel chan string +} + +var bt *customLogBeater +var gatewayConfig *config.GatewayConfig + +// New creates an instance of aws_apigw_traceability_agent. +func New(b *beat.Beat, cfg *common.Config) (beat.Beater, error) { + bt := &customLogBeater{ + done: make(chan struct{}), + eventChannel: make(chan string), + } + + var err error + bt.logReader, err = gateway.NewLogReader(gatewayConfig, bt.eventChannel) + bt.eventProcessor = gateway.NewEventProcessor(gatewayConfig) + if err != nil { + return nil, err + } + + if !gatewayConfig.ProcessOnInput { + traceability.SetOutputEventProcessor(bt.eventProcessor) + } + + // Validate that all necessary services are up and running. If not, return error + if hc.RunChecks() != hc.OK { + return nil, agenterrors.ErrInitServicesNotReady + } + + return bt, nil +} + +// SetGatewayConfig - set parsed gateway config +func SetGatewayConfig(gatewayCfg *config.GatewayConfig) { + gatewayConfig = gatewayCfg +} + +// Run starts awsApigwTraceabilityAgent. +func (bt *customLogBeater) Run(b *beat.Beat) error { + logp.Info("apic_traceability_agent is running! Hit CTRL-C to stop it.") + + var err error + bt.client, err = b.Publisher.Connect() + if err != nil { + return err + } + + bt.logReader.Start() + + for { + select { + case <-bt.done: + return nil + case eventData := <-bt.eventChannel: + if gatewayConfig.ProcessOnInput { + eventsToPublish := bt.eventProcessor.ProcessRaw([]byte(eventData)) + if eventsToPublish != nil { + bt.client.PublishAll(eventsToPublish) + } + } else { + eventToPublish := beat.Event{ + Fields: common.MapStr{ + "message": eventData, + }, + } + bt.client.Publish(eventToPublish) + } + } + } +} + +// Stop stops customLogTraceabilityAgent. +func (bt *customLogBeater) Stop() { + bt.client.Close() + close(bt.done) +} diff --git a/pkg/cmd/discovery/discoveryCmd.go b/pkg/cmd/discovery/discoveryCmd.go new file mode 100644 index 0000000..abe6b84 --- /dev/null +++ b/pkg/cmd/discovery/discoveryCmd.go @@ -0,0 +1,62 @@ +package discovery + +import ( + corecmd "github.com/Axway/agent-sdk/pkg/cmd" + corecfg "github.com/Axway/agent-sdk/pkg/config" + + config "github.com/Axway/agents-kong/pkg/config/discovery" + "github.com/Axway/agents-kong/pkg/gateway" +) + +var DiscoveryCmd corecmd.AgentRootCmd +var gatewayConfig *config.GatewayConfig + +func init() { + // Create new root command with callbacks to initialize the agent config and command execution. + // The first parameter identifies the name of the yaml file that agent will look for to load the config + DiscoveryCmd = corecmd.NewRootCmd( + "apic_discovery_agent", + "Start the Kong Discovery Agent", + initConfig, + run, + corecfg.DiscoveryAgent, + ) + + // Get the root command properties and bind the config property in YAML definition + rootProps := DiscoveryCmd.GetProperties() + // rootProps.AddStringProperty("gateway-section.specPath", "./apis/musical_instruments.json", "Sample Swagger specification path for discovery") + rootProps.AddStringProperty("gateway-section.config_key_1", "", "Config Key 1") + rootProps.AddStringProperty("gateway-section.config_key_2", "", "Config Key 1") + rootProps.AddStringProperty("gateway-section.config_key_3", "", "Config Key 3") +} + +// Callback that agent will call to process the execution +func run() error { + gatewayClient, err := gateway.NewClient(gatewayConfig) + err = gatewayClient.DiscoverAPIs() + return err +} + +// Callback that agent will call to initialize the config. CentralConfig is parsed by Agent SDK +// and passed to the callback allowing the agent code to access the central config +func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { + rootProps := DiscoveryCmd.GetProperties() + // Parse the config from bound properties and setup gateway config + gatewayConfig = &config.GatewayConfig{ + SpecPath: rootProps.StringPropertyValue("gateway-section.specPath"), + ConfigKey1: rootProps.StringPropertyValue("gateway-section.config_key_1"), + ConfigKey2: rootProps.StringPropertyValue("gateway-section.config_key_2"), + ConfigKey3: rootProps.StringPropertyValue("gateway-section.config_key_3"), + } + + agentConfig := config.AgentConfig{ + CentralCfg: centralConfig, + GatewayCfg: gatewayConfig, + } + return agentConfig, nil +} + +// GetAgentConfig - Returns the agent config +func GetAgentConfig() *config.GatewayConfig { + return gatewayConfig +} diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go new file mode 100644 index 0000000..d268368 --- /dev/null +++ b/pkg/cmd/root.go @@ -0,0 +1,27 @@ +package cmd + +import ( + "os" + + "github.com/Axway/agents-kong/pkg/cmd/discovery" + "github.com/Axway/agents-kong/pkg/cmd/traceability" + + "github.com/spf13/cobra" +) + +// RootCmd is the root +var RootCmd = &cobra.Command{ + Use: "kong-agent", + Short: "Kong Discovery & Traceability Agent", +} + +func Execute() { + if err := RootCmd.Execute(); err != nil { + os.Exit(1) + } +} + +func init() { + RootCmd.AddCommand(discovery.DiscoveryCmd.RootCmd()) + RootCmd.AddCommand(traceability.TraceCmd.RootCmd()) +} diff --git a/pkg/cmd/traceability/traceabilityCmd.go b/pkg/cmd/traceability/traceabilityCmd.go new file mode 100644 index 0000000..21d816f --- /dev/null +++ b/pkg/cmd/traceability/traceabilityCmd.go @@ -0,0 +1,70 @@ +package traceability + +import ( + corecmd "github.com/Axway/agent-sdk/pkg/cmd" + corecfg "github.com/Axway/agent-sdk/pkg/config" + "github.com/Axway/agents-kong/pkg/beater" + config "github.com/Axway/agents-kong/pkg/config/traceability" + libcmd "github.com/elastic/beats/v7/libbeat/cmd" + "github.com/elastic/beats/v7/libbeat/cmd/instance" +) + +var TraceCmd corecmd.AgentRootCmd +var beatCmd *libcmd.BeatsRootCmd + +func init() { + name := "apic_traceability_agent" + settings := instance.Settings{ + Name: name, + HasDashboards: true, + } + + beatCmd = libcmd.GenRootCmdWithSettings(beater.New, settings) + cmd := beatCmd.Command + // Wrap the beat command with the agent command processor with callbacks to initialize the agent config and command execution. + // The first parameter identifies the name of the yaml file that agent will look for to load the config + TraceCmd = corecmd.NewCmd( + &cmd, + name, + "Start the Kong Traceability Agent", + initConfig, + run, + corecfg.TraceabilityAgent, + ) + + // Get the root command properties and bind the config property in YAML definition + + rootProps := TraceCmd.GetProperties() + // rootProps.AddStringProperty("gateway-section.logFile", "./logs/traffic.log", "Sample log file with traffic event from gateway") + rootProps.AddBoolProperty("gateway-section.processOnInput", true, "Flag to process received event on input or by output before publishing the event by transport") + rootProps.AddStringProperty("gateway-section.config_key_1", "", "Sample Config Key 1") + rootProps.AddStringProperty("gateway-section.config_key_2", "", "Sample Config Key 1") + rootProps.AddStringProperty("gateway-section.config_key_3", "", "Sample Config Key 3") +} + +// Callback that agent will call to process the execution +func run() error { + return beatCmd.Execute() +} + +// Callback that agent will call to initialize the config. CentralConfig is parsed by Agent SDK +// and passed to the callback allowing the agent code to access the central config +func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { + rootProps := TraceCmd.GetProperties() + // Parse the config from bound properties and setup gateway config + gatewayConfig := &config.GatewayConfig{ + LogFile: rootProps.StringPropertyValue("gateway-section.logFile"), + ProcessOnInput: rootProps.BoolPropertyValue("gateway-section.processOnInput"), + ConfigKey1: rootProps.StringPropertyValue("gateway-section.config_key_1"), + ConfigKey2: rootProps.StringPropertyValue("gateway-section.config_key_2"), + ConfigKey3: rootProps.StringPropertyValue("gateway-section.config_key_3"), + } + + agentConfig := &config.AgentConfig{ + CentralCfg: centralConfig, + GatewayCfg: gatewayConfig, + } + beater.SetGatewayConfig(gatewayConfig) + + return agentConfig, nil +} diff --git a/pkg/config/discovery/config.go b/pkg/config/discovery/config.go new file mode 100644 index 0000000..37988ac --- /dev/null +++ b/pkg/config/discovery/config.go @@ -0,0 +1,31 @@ +package config + +import ( + "errors" + + corecfg "github.com/Axway/agent-sdk/pkg/config" +) + +// AgentConfig - represents the config for agent +type AgentConfig struct { + CentralCfg corecfg.CentralConfig `config:"central"` + GatewayCfg *GatewayConfig `config:"gateway-section"` +} + +// GatewayConfig - represents the config for gateway +type GatewayConfig struct { + corecfg.IConfigValidator + SpecPath string `config:"specPath"` + ConfigKey1 string `config:"config_key_1"` + ConfigKey2 string `config:"config_key_2"` + ConfigKey3 string `config:"config_key_3"` +} + +// ValidateCfg - Validates the gateway config +func (c *GatewayConfig) ValidateCfg() (err error) { + if c.SpecPath == "" { + return errors.New("Invalid gateway configuration: specPath is not configured") + } + + return +} diff --git a/pkg/config/traceability/config.go b/pkg/config/traceability/config.go new file mode 100644 index 0000000..3eff7c6 --- /dev/null +++ b/pkg/config/traceability/config.go @@ -0,0 +1,32 @@ +package config + +import ( + "errors" + + corecfg "github.com/Axway/agent-sdk/pkg/config" +) + +// AgentConfig - represents the config for agent +type AgentConfig struct { + CentralCfg corecfg.CentralConfig `config:"central"` + GatewayCfg *GatewayConfig `config:"gateway-section"` +} + +// GatewayConfig - represents the config for gateway +type GatewayConfig struct { + corecfg.IConfigValidator + LogFile string `config:"logFile"` + ProcessOnInput bool `config:"processOnInput"` + ConfigKey1 string `config:"config_key_1"` + ConfigKey2 string `config:"config_key_2"` + ConfigKey3 string `config:"config_key_3"` +} + +// ValidateCfg - Validates the gateway config +func (c *GatewayConfig) ValidateCfg() (err error) { + if c.LogFile == "" { + return errors.New("Invalid gateway configuration: logFile is not configured") + } + + return +} diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go new file mode 100644 index 0000000..fa52fc3 --- /dev/null +++ b/pkg/gateway/client.go @@ -0,0 +1,88 @@ +package gateway + +import ( + "io/ioutil" + + "github.com/Axway/agent-sdk/pkg/agent" + "github.com/Axway/agent-sdk/pkg/apic" + "github.com/Axway/agent-sdk/pkg/util/log" + config "github.com/Axway/agents-kong/pkg/config/discovery" +) + +// GatewayClient - Represents the Gateway client +type GatewayClient struct { + cfg *config.GatewayConfig +} + +// NewClient - Creates a new Gateway Client +func NewClient(gatewayCfg *config.GatewayConfig) (*GatewayClient, error) { + return &GatewayClient{ + cfg: gatewayCfg, + }, nil +} + +// ExternalAPI - Sample struct representing the API definition in API gateway +type ExternalAPI struct { + swaggerSpec []byte + id string + name string + description string + version string + url string + documentation []byte +} + +// DiscoverAPIs - Process the API discovery +func (a *GatewayClient) DiscoverAPIs() error { + // Gateway specific implementation to get the details for discovered API goes here + // Set the service definition + // As sample the implementation reads the swagger for musical-instrument from local directory + swaggerSpec, err := a.getSpec() + if err != nil { + log.Infof("Failed to load sample API specification from %s: %s ", a.cfg.SpecPath, err.Error()) + } + + externalAPI := ExternalAPI{ + id: "65c79285-f550-4617-bf6e-003e617841f2", + name: "Musical-Instrument-Sample", + description: "Sample for API discovery agent", + version: "1.0.0", + url: "", + documentation: []byte("\"Sample documentation for API discovery agent\""), + swaggerSpec: swaggerSpec, + } + + serviceBody, err := a.buildServiceBody(externalAPI) + if err != nil { + return err + } + err = agent.PublishAPI(serviceBody) + if err != nil { + return err + } + log.Info("Published API " + serviceBody.APIName + "to AMPLIFY Central") + return err +} + +// buildServiceBody - creates the service definition +func (a *GatewayClient) buildServiceBody(externalAPI ExternalAPI) (apic.ServiceBody, error) { + return apic.NewServiceBodyBuilder(). + SetID(externalAPI.id). + SetTitle(externalAPI.name). + SetURL(externalAPI.url). + SetDescription(externalAPI.description). + SetAPISpec(externalAPI.swaggerSpec). + SetVersion(externalAPI.version). + SetAuthPolicy(apic.Passthrough). + SetDocumentation(externalAPI.documentation). + SetResourceType(apic.Oas2). + Build() +} + +func (a *GatewayClient) getSpec() ([]byte, error) { + bytes, err := ioutil.ReadFile(a.cfg.SpecPath) + if err != nil { + return nil, err + } + return bytes, nil +} diff --git a/pkg/gateway/definitions.go b/pkg/gateway/definitions.go new file mode 100644 index 0000000..915f1c9 --- /dev/null +++ b/pkg/gateway/definitions.go @@ -0,0 +1,28 @@ +package gateway + +// Headers - Type for request/response headers +type Headers map[string]string + +// GwTransaction - Type for gateway transaction detail +type GwTransaction struct { + ID string `json:"id"` + SourceHost string `json:"srcHost"` + SourcePort int `json:"srcPort"` + DesHost string `json:"destHost"` + DestPort int `json:"destPort"` + URI string `json:"uri"` + Method string `json:"method"` + StatusCode int `json:"statusCode"` + RequestHeaders Headers `json:"requestHeaders"` + ResponseHeaders Headers `json:"responseHeaders"` + RequestBytes int `json:"requestByte"` + ResponseBytes int `json:"responseByte"` +} + +// GwTrafficLogEntry - Represents the structure of log entry the agent will receive +type GwTrafficLogEntry struct { + TraceID string `json:"traceId"` + APIName string `json:"apiName"` + InboundTransaction GwTransaction `json:"inbound"` + OutboundTransaction GwTransaction `json:"outbound"` +} diff --git a/pkg/gateway/eventmapper.go b/pkg/gateway/eventmapper.go new file mode 100644 index 0000000..51d8cff --- /dev/null +++ b/pkg/gateway/eventmapper.go @@ -0,0 +1,123 @@ +package gateway + +import ( + "encoding/json" + "net/http" + "strconv" + "time" + + "github.com/Axway/agent-sdk/pkg/agent" + "github.com/Axway/agent-sdk/pkg/transaction" + "github.com/Axway/agent-sdk/pkg/util/log" +) + +// EventMapper - +type EventMapper struct { +} + +func (m *EventMapper) processMapping(gatewayTrafficLogEntry GwTrafficLogEntry) ([]*transaction.LogEvent, error) { + centralCfg := agent.GetCentralConfig() + + eventTime := time.Now().Unix() + txID := gatewayTrafficLogEntry.TraceID + txEventID := gatewayTrafficLogEntry.InboundTransaction.ID + txDetails := gatewayTrafficLogEntry.InboundTransaction + transInboundLogEventLeg, err := m.createTransactionEvent(eventTime, txID, txDetails, txEventID, "", "Inbound") + if err != nil { + return nil, err + } + + txEventID = gatewayTrafficLogEntry.OutboundTransaction.ID + txParentEventID := gatewayTrafficLogEntry.InboundTransaction.ID + txDetails = gatewayTrafficLogEntry.OutboundTransaction + transOutboundLogEventLeg, err := m.createTransactionEvent(eventTime, txID, txDetails, txEventID, txParentEventID, "Outbound") + if err != nil { + return nil, err + } + + transSummaryLogEvent, err := m.createSummaryEvent(eventTime, txID, gatewayTrafficLogEntry, centralCfg.GetTeamID()) + if err != nil { + return nil, err + } + + return []*transaction.LogEvent{ + transSummaryLogEvent, + transInboundLogEventLeg, + transOutboundLogEventLeg, + }, nil +} + +func (m *EventMapper) getTransactionEventStatus(code int) transaction.TxEventStatus { + if code >= 400 { + return transaction.TxEventStatusFail + } + return transaction.TxEventStatusFail +} + +func (m *EventMapper) getTransactionSummaryStatus(statusCode int) transaction.TxSummaryStatus { + transSummaryStatus := transaction.TxSummaryStatusUnknown + if statusCode >= http.StatusOK && statusCode < http.StatusBadRequest { + transSummaryStatus = transaction.TxSummaryStatusSuccess + } else if statusCode >= http.StatusBadRequest && statusCode < http.StatusInternalServerError { + transSummaryStatus = transaction.TxSummaryStatusFailure + } else if statusCode >= http.StatusInternalServerError && statusCode < http.StatusNetworkAuthenticationRequired { + transSummaryStatus = transaction.TxSummaryStatusException + } + return transSummaryStatus +} + +func (m *EventMapper) buildHeaders(headers map[string]string) string { + jsonHeader, err := json.Marshal(headers) + if err != nil { + log.Error(err.Error()) + } + return string(jsonHeader) +} + +func (m *EventMapper) createTransactionEvent(eventTime int64, txID string, txDetails GwTransaction, eventID, parentEventID, direction string) (*transaction.LogEvent, error) { + + httpProtocolDetails, err := transaction.NewHTTPProtocolBuilder(). + SetURI(txDetails.URI). + SetMethod(txDetails.Method). + SetStatus(txDetails.StatusCode, http.StatusText(txDetails.StatusCode)). + SetHost(txDetails.SourceHost). + SetHeaders(m.buildHeaders(txDetails.RequestHeaders), m.buildHeaders(txDetails.ResponseHeaders)). + SetByteLength(txDetails.RequestBytes, txDetails.ResponseBytes). + SetRemoteAddress("", txDetails.DesHost, txDetails.DestPort). + SetLocalAddress(txDetails.SourceHost, txDetails.SourcePort). + Build() + if err != nil { + return nil, err + } + + return transaction.NewTransactionEventBuilder(). + SetTimestamp(eventTime). + SetTransactionID(txID). + SetID(eventID). + SetParentID(parentEventID). + SetSource(txDetails.SourceHost + ":" + strconv.Itoa(txDetails.SourcePort)). + SetDestination(txDetails.DesHost + ":" + strconv.Itoa(txDetails.DestPort)). + SetDirection(direction). + SetStatus(m.getTransactionEventStatus(txDetails.StatusCode)). + SetProtocolDetail(httpProtocolDetails). + Build() +} + +func (m *EventMapper) createSummaryEvent(eventTime int64, txID string, gatewayTrafficLogEntry GwTrafficLogEntry, teamID string) (*transaction.LogEvent, error) { + statusCode := gatewayTrafficLogEntry.InboundTransaction.StatusCode + method := gatewayTrafficLogEntry.InboundTransaction.Method + uri := gatewayTrafficLogEntry.InboundTransaction.URI + host := gatewayTrafficLogEntry.InboundTransaction.SourceHost + + return transaction.NewTransactionSummaryBuilder(). + SetTimestamp(eventTime). + SetTransactionID(txID). + SetStatus(m.getTransactionSummaryStatus(statusCode), strconv.Itoa(statusCode)). + SetTeam(teamID). + SetEntryPoint("http", method, uri, host). + // If the API is published to Central as unified catalog item/API service, se the Proxy details with the API definition + // The Proxy.Name represents the name of the API + // The Proxy.ID should be of format "remoteApiId_". Use transaction.FormatProxyID() to get the formatted value. + SetProxy("unknown", "", 0). + Build() +} diff --git a/pkg/gateway/eventprocessor.go b/pkg/gateway/eventprocessor.go new file mode 100644 index 0000000..e5254bb --- /dev/null +++ b/pkg/gateway/eventprocessor.go @@ -0,0 +1,93 @@ +package gateway + +import ( + "encoding/json" + "time" + + "github.com/Axway/agent-sdk/pkg/transaction" + "github.com/Axway/agent-sdk/pkg/util/log" + config "github.com/Axway/agents-kong/pkg/config/traceability" + + "github.com/elastic/beats/v7/libbeat/beat" + "github.com/elastic/beats/v7/libbeat/publisher" +) + +// EventProcessor - represents the processor for received event to generate event(s) for AMPLIFY Central +// The event processing can be done either when the beat input receives the log entry or before the beat transport +// publishes the event to transport. +// When processing the received log entry on input, the log entry is mapped to structure expected for AMPLIFY Central Observer +// and then beat.Event is published to beat output that produces the event over the configured transport. +// When processing the log entry on output, the log entry is published to output as beat.Event. The output transport invokes +// the Process(events []publisher.Event) method which is set as output event processor. The Process() method processes the received +// log entry and performs the mapping to structure expected for AMPLIFY Central Observer. The method returns the converted Events to +// transport publisher which then produces the events over the transport. +type EventProcessor struct { + cfg *config.GatewayConfig + eventGenerator transaction.EventGenerator + eventMapper *EventMapper +} + +// NewEventProcessor - return a new EventProcessor +func NewEventProcessor(gateway *config.GatewayConfig) *EventProcessor { + ep := &EventProcessor{ + cfg: gateway, + eventGenerator: transaction.NewEventGenerator(), + eventMapper: &EventMapper{}, + } + return ep +} + +// Process - callback set as output event processor that gets invoked by transport publisher to process the received events +func (p *EventProcessor) Process(events []publisher.Event) []publisher.Event { + newEvents := make([]publisher.Event, 0) + for _, event := range events { + // Get the message from the log file + eventMsgFieldVal, err := event.Content.Fields.GetValue("message") + if err != nil { + log.Error(err.Error()) + return newEvents + } + + eventMsg, ok := eventMsgFieldVal.(string) + if ok { + // Unmarshal the message into the struct representing traffic log entry in gateway logs + beatEvents := p.ProcessRaw([]byte(eventMsg)) + if beatEvents != nil { + for _, beatEvent := range beatEvents { + publisherEvent := publisher.Event{ + Content: beatEvent, + } + newEvents = append(newEvents, publisherEvent) + } + } + } + } + return newEvents +} + +// ProcessRaw - process the received log entry and returns the event to be published to AMPLIFY ingestion service +func (p *EventProcessor) ProcessRaw(rawEventData []byte) []beat.Event { + var gatewayTrafficLogEntry GwTrafficLogEntry + err := json.Unmarshal(rawEventData, &gatewayTrafficLogEntry) + if err != nil { + log.Error(err.Error()) + return nil + } + // Map the log entry to log event structure expected by AMPLIFY Central Observer + logEvents, err := p.eventMapper.processMapping(gatewayTrafficLogEntry) + if err != nil { + log.Error(err.Error()) + return nil + } + events := make([]beat.Event, 0) + for _, logEvent := range logEvents { + // Generates the beat.Event with attributes by AMPLIFY ingestion service + event, err := p.eventGenerator.CreateEvent(*logEvent, time.Now(), nil, nil, nil) + if err != nil { + log.Error(err.Error()) + } else { + events = append(events, event) + } + } + return events +} diff --git a/pkg/gateway/logreader.go b/pkg/gateway/logreader.go new file mode 100644 index 0000000..8ac72f9 --- /dev/null +++ b/pkg/gateway/logreader.go @@ -0,0 +1,32 @@ +package gateway + +import ( + config "github.com/Axway/agents-kong/pkg/config/traceability" + "github.com/hpcloud/tail" +) + +// LogReader - Represents the Gateway client +type LogReader struct { + cfg *config.GatewayConfig + eventChannel chan string +} + +// NewLogReader - Creates a new Gateway Client +func NewLogReader(gatewayCfg *config.GatewayConfig, eventChannel chan string) (*LogReader, error) { + return &LogReader{ + cfg: gatewayCfg, + eventChannel: eventChannel, + }, nil +} + +// Start - Starts reading log file +func (r *LogReader) Start() { + go r.tailFile() +} + +func (r LogReader) tailFile() { + t, _ := tail.TailFile(r.cfg.LogFile, tail.Config{Follow: true}) + for line := range t.Lines { + r.eventChannel <- line.Text + } +} From 666d285897aed12e0501798a753d5f9ca021f032 Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Tue, 26 Jan 2021 15:36:03 -0700 Subject: [PATCH 03/76] remove .idea --- .gitignore | 3 +- .idea/agents-kong.iml | 9 ----- .idea/modules.xml | 8 ----- .idea/vcs.xml | 6 ---- .idea/watcherTasks.xml | 9 ----- .idea/workspace.xml | 81 ------------------------------------------ 6 files changed, 2 insertions(+), 114 deletions(-) delete mode 100644 .idea/agents-kong.iml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml delete mode 100644 .idea/watcherTasks.xml delete mode 100644 .idea/workspace.xml diff --git a/.gitignore b/.gitignore index 8ddb00d..f02c3f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .env apic_discovery_agent.yml -apic_traceability_agent.yml \ No newline at end of file +apic_traceability_agent.yml +.idea/ \ No newline at end of file diff --git a/.idea/agents-kong.iml b/.idea/agents-kong.iml deleted file mode 100644 index 5e764c4..0000000 --- a/.idea/agents-kong.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 24dc88f..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/watcherTasks.xml b/.idea/watcherTasks.xml deleted file mode 100644 index 27aa2e8..0000000 --- a/.idea/watcherTasks.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index bc52b61..0000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1611686013581 - - - - - - - - - - true - - \ No newline at end of file From 9732d7199fcb1e4db58c18fb1faf5bbd3df7ec29 Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Tue, 26 Jan 2021 16:30:39 -0700 Subject: [PATCH 04/76] ignore folders --- .gitignore | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f02c3f8..7aec658 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,25 @@ +*.exe +*.exe~ +*.dll +*.so +*.dylib +*.test +*.out + +dist/ +coverage/ +**/local-values.yaml +.vscode/ +bin/ +.idea/ +**.tgz +.log .env +*.pem +*.key +.DS_Store +.run/ +*.log + apic_discovery_agent.yml apic_traceability_agent.yml -.idea/ \ No newline at end of file From ea2bf5e85abfcfb6595e564568bf60bc4ee323ae Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Tue, 26 Jan 2021 17:40:13 -0700 Subject: [PATCH 05/76] build --- Makefile | 11 ++++++++++- README.md | 8 +++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e4dd4f6..1962a93 100644 --- a/Makefile +++ b/Makefile @@ -8,4 +8,13 @@ tidy: go.mod @go mod tidy download: tidy - @go mod download \ No newline at end of file + @go mod download + +build: + @go build -o bin/agents-kong ./cmd/main.go + +run-discovery: + ./bin/agents-kong apic_discovery_agent + +run-traceability: + ./bin/agents-kong apic_traceability_agent \ No newline at end of file diff --git a/README.md b/README.md index daf7de5..7a0089b 100644 --- a/README.md +++ b/README.md @@ -1 +1,7 @@ -# agents-kong \ No newline at end of file +# agents-kong + +To build the agents run `make build` + +To run the discovery agent run `make run-discovery` + +To run the traceability agent run `make run-traceability` \ No newline at end of file From 8c66e408a36b5b42c17f8906927e6acf3aeca751 Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Wed, 27 Jan 2021 12:31:18 -0700 Subject: [PATCH 06/76] update --- .gitignore | 4 +-- .golangci.yml | 32 ++++++++++++++++++ Makefile | 8 ++++- default_apic_discovery_agent.yml | 14 -------- default_kong_discovery_agent.yml | 28 ++++++++++++++++ ...yml => default_kong_traceability_agent.yml | 33 +++++++++++-------- pkg/beater/custom_log_filebeater.go | 4 +-- pkg/cmd/discovery/discoveryCmd.go | 10 +++--- pkg/cmd/traceability/traceabilityCmd.go | 9 ++--- 9 files changed, 98 insertions(+), 44 deletions(-) create mode 100644 .golangci.yml delete mode 100644 default_apic_discovery_agent.yml create mode 100644 default_kong_discovery_agent.yml rename default_apic_traceability_agent.yml => default_kong_traceability_agent.yml (72%) diff --git a/.gitignore b/.gitignore index 7aec658..c891cc8 100644 --- a/.gitignore +++ b/.gitignore @@ -21,5 +21,5 @@ bin/ .run/ *.log -apic_discovery_agent.yml -apic_traceability_agent.yml +kong_discovery_agent.yml +kong_traceability_agent.yml diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..af6d153 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,32 @@ +run: + timeout: 8m + modules-download-mode: readonly +linters: + disable-all: true + enable: + - govet + - errcheck + - staticcheck + - unused + - structcheck + - varcheck + - deadcode + - bodyclose + - depguard + - golint + - dogsled + - dupl + - goconst + - gocritic + - gocyclo + - gofmt + - goimports + - gosimple + - ineffassign + - misspell + - nakedret + - scopelint + - stylecheck + - typecheck + - unconvert + - unparam diff --git a/Makefile b/Makefile index 1962a93..aeffdfd 100644 --- a/Makefile +++ b/Makefile @@ -17,4 +17,10 @@ run-discovery: ./bin/agents-kong apic_discovery_agent run-traceability: - ./bin/agents-kong apic_traceability_agent \ No newline at end of file + ./bin/agents-kong apic_traceability_agent + +lint: + @golangci-lint run -v + +lint-fix: + @golangci-lint run -v --fix \ No newline at end of file diff --git a/default_apic_discovery_agent.yml b/default_apic_discovery_agent.yml deleted file mode 100644 index f6d102d..0000000 --- a/default_apic_discovery_agent.yml +++ /dev/null @@ -1,14 +0,0 @@ -# this is a sample config file. Copy the content of this file to a new file named apic_discovery_agent.yml -central: - organizationID: "" - environment: - auth: - clientID: - privateKey: - publicKey: - -gateway-section: - specPath: ./apis/musical_instruments.json - config_key_1: value - config_key_2: value - config_key_3: value diff --git a/default_kong_discovery_agent.yml b/default_kong_discovery_agent.yml new file mode 100644 index 0000000..a877381 --- /dev/null +++ b/default_kong_discovery_agent.yml @@ -0,0 +1,28 @@ +# this is a sample config file. Copy the content of this file to a new file named kong_discovery_agent.yml +central: + environment: + mode: publishToEnvironment + organizationID: "" + platformURL: + pollInterval: 20s + team: "Default Team" + url: + auth: + clientID: + privateKey: + publicKey: + realm: Broker + timeout: 20s + url: https://login-preprod.axway.com/auth + +log: + level: debug + format: json + output: stdout + path: logs + +kong: + admin_endpoint: + proxy_endpoint: + token: 1234 + user: admin diff --git a/default_apic_traceability_agent.yml b/default_kong_traceability_agent.yml similarity index 72% rename from default_apic_traceability_agent.yml rename to default_kong_traceability_agent.yml index 999e374..2b69d68 100644 --- a/default_apic_traceability_agent.yml +++ b/default_kong_traceability_agent.yml @@ -1,27 +1,28 @@ -# this is a sample config file. Copy the content of this file to a new file named apic_traceability_agent.yml -apic_traceability_agent: +# this is a sample config file. Copy the content of this file to a new file named kong_traceability_agent.yml +kong_traceability_agent: central: - organizationID: "" environment: + mode: publishToEnvironment + organizationID: "" + platformURL: + pollInterval: 20s + team: "Default Team" + url: auth: clientID: privateKey: publicKey: - - gateway-section: - logFile: ./logs/traffic.log - processOnInput: false - config_key_1: "value-1" - config_key_3: "value-2" - config_key_2: "value-3" + realm: Broker + timeout: 20s + url: https://login-preprod.axway.com/auth # Condor Ingestion service output.traceability: + compression_level: ${TRACEABILITY_COMPRESSIONLEVEL:3} enabled: true hosts: - ${TRACEABILITY_HOST:"ingestion-lumberjack.datasearch.axway.com:453"} protocol: ${TRACEABILITY_PROTOCOL:"tcp"} - compression_level: ${TRACEABILITY_COMPRESSIONLEVEL:3} ssl: enabled: true verification_mode: none @@ -40,7 +41,11 @@ output.traceability: logging: metrics: enabled: false - # Send all logging output to stderr to_stderr: true - # Set log level - level: ${LOG_LEVEL:"info"} \ No newline at end of file + level: ${LOG_LEVEL:"info"} + +kong: + admin_endpoint: + proxy_endpoint: + token: 1234 + user: admin \ No newline at end of file diff --git a/pkg/beater/custom_log_filebeater.go b/pkg/beater/custom_log_filebeater.go index 69a8f39..5bf89cb 100644 --- a/pkg/beater/custom_log_filebeater.go +++ b/pkg/beater/custom_log_filebeater.go @@ -2,7 +2,7 @@ package beater import ( "github.com/Axway/agent-sdk/pkg/traceability" - agenterrors "github.com/Axway/agent-sdk/pkg/util/errors" + agentErrors "github.com/Axway/agent-sdk/pkg/util/errors" hc "github.com/Axway/agent-sdk/pkg/util/healthcheck" "github.com/elastic/beats/v7/libbeat/beat" @@ -45,7 +45,7 @@ func New(b *beat.Beat, cfg *common.Config) (beat.Beater, error) { // Validate that all necessary services are up and running. If not, return error if hc.RunChecks() != hc.OK { - return nil, agenterrors.ErrInitServicesNotReady + return nil, agentErrors.ErrInitServicesNotReady } return bt, nil diff --git a/pkg/cmd/discovery/discoveryCmd.go b/pkg/cmd/discovery/discoveryCmd.go index abe6b84..f9e6e52 100644 --- a/pkg/cmd/discovery/discoveryCmd.go +++ b/pkg/cmd/discovery/discoveryCmd.go @@ -15,7 +15,7 @@ func init() { // Create new root command with callbacks to initialize the agent config and command execution. // The first parameter identifies the name of the yaml file that agent will look for to load the config DiscoveryCmd = corecmd.NewRootCmd( - "apic_discovery_agent", + "kong_discovery_agent", "Start the Kong Discovery Agent", initConfig, run, @@ -24,10 +24,10 @@ func init() { // Get the root command properties and bind the config property in YAML definition rootProps := DiscoveryCmd.GetProperties() - // rootProps.AddStringProperty("gateway-section.specPath", "./apis/musical_instruments.json", "Sample Swagger specification path for discovery") - rootProps.AddStringProperty("gateway-section.config_key_1", "", "Config Key 1") - rootProps.AddStringProperty("gateway-section.config_key_2", "", "Config Key 1") - rootProps.AddStringProperty("gateway-section.config_key_3", "", "Config Key 3") + rootProps.AddStringProperty("kong.user", "", "Kong Gateway user") + rootProps.AddStringProperty("kong.token", "", "Token to authenticate with Kong Gateway") + rootProps.AddStringProperty("kong.admin_endpoint", "", "The Kong Admin endpoint") + rootProps.AddStringProperty("kong.proxy_endpoint", "", "The Kong Proxy endpoint") } // Callback that agent will call to process the execution diff --git a/pkg/cmd/traceability/traceabilityCmd.go b/pkg/cmd/traceability/traceabilityCmd.go index 21d816f..7f2cef8 100644 --- a/pkg/cmd/traceability/traceabilityCmd.go +++ b/pkg/cmd/traceability/traceabilityCmd.go @@ -13,7 +13,7 @@ var TraceCmd corecmd.AgentRootCmd var beatCmd *libcmd.BeatsRootCmd func init() { - name := "apic_traceability_agent" + name := "kong_traceability_agent" settings := instance.Settings{ Name: name, HasDashboards: true, @@ -35,11 +35,8 @@ func init() { // Get the root command properties and bind the config property in YAML definition rootProps := TraceCmd.GetProperties() - // rootProps.AddStringProperty("gateway-section.logFile", "./logs/traffic.log", "Sample log file with traffic event from gateway") - rootProps.AddBoolProperty("gateway-section.processOnInput", true, "Flag to process received event on input or by output before publishing the event by transport") - rootProps.AddStringProperty("gateway-section.config_key_1", "", "Sample Config Key 1") - rootProps.AddStringProperty("gateway-section.config_key_2", "", "Sample Config Key 1") - rootProps.AddStringProperty("gateway-section.config_key_3", "", "Sample Config Key 3") + rootProps.AddStringProperty("kong.user", "", "Kong Gateway user") + rootProps.AddStringProperty("kong.token", "", "Token to authenticate with Kong Gateway") } // Callback that agent will call to process the execution From 4a6995ba259176d888df8ad971831128b9504529 Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Wed, 27 Jan 2021 13:07:35 -0700 Subject: [PATCH 07/76] update --- default_kong_traceability_agent.yml | 1 - pkg/cmd/discovery/discoveryCmd.go | 12 ++++++------ pkg/cmd/traceability/traceabilityCmd.go | 17 ++++++++++------- pkg/config/discovery/config.go | 16 +++++----------- pkg/config/traceability/config.go | 10 +++++----- pkg/gateway/client.go | 9 ++------- 6 files changed, 28 insertions(+), 37 deletions(-) diff --git a/default_kong_traceability_agent.yml b/default_kong_traceability_agent.yml index 2b69d68..a8701f4 100644 --- a/default_kong_traceability_agent.yml +++ b/default_kong_traceability_agent.yml @@ -5,7 +5,6 @@ kong_traceability_agent: mode: publishToEnvironment organizationID: "" platformURL: - pollInterval: 20s team: "Default Team" url: auth: diff --git a/pkg/cmd/discovery/discoveryCmd.go b/pkg/cmd/discovery/discoveryCmd.go index f9e6e52..d435897 100644 --- a/pkg/cmd/discovery/discoveryCmd.go +++ b/pkg/cmd/discovery/discoveryCmd.go @@ -16,7 +16,7 @@ func init() { // The first parameter identifies the name of the yaml file that agent will look for to load the config DiscoveryCmd = corecmd.NewRootCmd( "kong_discovery_agent", - "Start the Kong Discovery Agent", + "Kong Discovery Agent", initConfig, run, corecfg.DiscoveryAgent, @@ -24,7 +24,7 @@ func init() { // Get the root command properties and bind the config property in YAML definition rootProps := DiscoveryCmd.GetProperties() - rootProps.AddStringProperty("kong.user", "", "Kong Gateway user") + rootProps.AddStringProperty("kong.user", "", "Kong Gateway admin user") rootProps.AddStringProperty("kong.token", "", "Token to authenticate with Kong Gateway") rootProps.AddStringProperty("kong.admin_endpoint", "", "The Kong Admin endpoint") rootProps.AddStringProperty("kong.proxy_endpoint", "", "The Kong Proxy endpoint") @@ -43,10 +43,10 @@ func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { rootProps := DiscoveryCmd.GetProperties() // Parse the config from bound properties and setup gateway config gatewayConfig = &config.GatewayConfig{ - SpecPath: rootProps.StringPropertyValue("gateway-section.specPath"), - ConfigKey1: rootProps.StringPropertyValue("gateway-section.config_key_1"), - ConfigKey2: rootProps.StringPropertyValue("gateway-section.config_key_2"), - ConfigKey3: rootProps.StringPropertyValue("gateway-section.config_key_3"), + AdminEndpoint: rootProps.StringPropertyValue("kong.admin_endpoint"), + ProxyEndpoint: rootProps.StringPropertyValue("kong.proxy_endpoint"), + Token: rootProps.StringPropertyValue("kong.token"), + User: rootProps.StringPropertyValue("kong.user"), } agentConfig := config.AgentConfig{ diff --git a/pkg/cmd/traceability/traceabilityCmd.go b/pkg/cmd/traceability/traceabilityCmd.go index 7f2cef8..c2220d9 100644 --- a/pkg/cmd/traceability/traceabilityCmd.go +++ b/pkg/cmd/traceability/traceabilityCmd.go @@ -26,7 +26,7 @@ func init() { TraceCmd = corecmd.NewCmd( &cmd, name, - "Start the Kong Traceability Agent", + "Kong Traceability Agent", initConfig, run, corecfg.TraceabilityAgent, @@ -35,8 +35,10 @@ func init() { // Get the root command properties and bind the config property in YAML definition rootProps := TraceCmd.GetProperties() - rootProps.AddStringProperty("kong.user", "", "Kong Gateway user") + rootProps.AddStringProperty("kong.user", "", "Kong Gateway admin user") rootProps.AddStringProperty("kong.token", "", "Token to authenticate with Kong Gateway") + rootProps.AddStringProperty("kong.admin_endpoint", "", "The Kong Admin endpoint") + rootProps.AddStringProperty("kong.proxy_endpoint", "", "The Kong Proxy endpoint") } // Callback that agent will call to process the execution @@ -50,11 +52,12 @@ func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { rootProps := TraceCmd.GetProperties() // Parse the config from bound properties and setup gateway config gatewayConfig := &config.GatewayConfig{ - LogFile: rootProps.StringPropertyValue("gateway-section.logFile"), - ProcessOnInput: rootProps.BoolPropertyValue("gateway-section.processOnInput"), - ConfigKey1: rootProps.StringPropertyValue("gateway-section.config_key_1"), - ConfigKey2: rootProps.StringPropertyValue("gateway-section.config_key_2"), - ConfigKey3: rootProps.StringPropertyValue("gateway-section.config_key_3"), + // LogFile: rootProps.StringPropertyValue("gateway-section.logFile"), + // ProcessOnInput: rootProps.BoolPropertyValue("gateway-section.processOnInput"), + AdminEndpoint: rootProps.StringPropertyValue("kong.admin_endpoint"), + ProxyEndpoint: rootProps.StringPropertyValue("kong.proxy_endpoint"), + Token: rootProps.StringPropertyValue("kong.token"), + User: rootProps.StringPropertyValue("kong.user"), } agentConfig := &config.AgentConfig{ diff --git a/pkg/config/discovery/config.go b/pkg/config/discovery/config.go index 37988ac..1b8b653 100644 --- a/pkg/config/discovery/config.go +++ b/pkg/config/discovery/config.go @@ -1,31 +1,25 @@ package config import ( - "errors" - corecfg "github.com/Axway/agent-sdk/pkg/config" ) // AgentConfig - represents the config for agent type AgentConfig struct { CentralCfg corecfg.CentralConfig `config:"central"` - GatewayCfg *GatewayConfig `config:"gateway-section"` + GatewayCfg *GatewayConfig `config:"kong"` } // GatewayConfig - represents the config for gateway type GatewayConfig struct { corecfg.IConfigValidator - SpecPath string `config:"specPath"` - ConfigKey1 string `config:"config_key_1"` - ConfigKey2 string `config:"config_key_2"` - ConfigKey3 string `config:"config_key_3"` + AdminEndpoint string `config:"adminEndpoint"` + ProxyEndpoint string `config:"proxyEndpoint"` + Token string `config:"token"` + User string `config:"user"` } // ValidateCfg - Validates the gateway config func (c *GatewayConfig) ValidateCfg() (err error) { - if c.SpecPath == "" { - return errors.New("Invalid gateway configuration: specPath is not configured") - } - return } diff --git a/pkg/config/traceability/config.go b/pkg/config/traceability/config.go index 3eff7c6..fe7f54e 100644 --- a/pkg/config/traceability/config.go +++ b/pkg/config/traceability/config.go @@ -9,7 +9,7 @@ import ( // AgentConfig - represents the config for agent type AgentConfig struct { CentralCfg corecfg.CentralConfig `config:"central"` - GatewayCfg *GatewayConfig `config:"gateway-section"` + GatewayCfg *GatewayConfig `config:"kong"` } // GatewayConfig - represents the config for gateway @@ -17,9 +17,10 @@ type GatewayConfig struct { corecfg.IConfigValidator LogFile string `config:"logFile"` ProcessOnInput bool `config:"processOnInput"` - ConfigKey1 string `config:"config_key_1"` - ConfigKey2 string `config:"config_key_2"` - ConfigKey3 string `config:"config_key_3"` + AdminEndpoint string `config:"adminEndpoint"` + ProxyEndpoint string `config:"proxyEndpoint"` + Token string `config:"token"` + User string `config:"user"` } // ValidateCfg - Validates the gateway config @@ -27,6 +28,5 @@ func (c *GatewayConfig) ValidateCfg() (err error) { if c.LogFile == "" { return errors.New("Invalid gateway configuration: logFile is not configured") } - return } diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index fa52fc3..24a2485 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -1,8 +1,6 @@ package gateway import ( - "io/ioutil" - "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/apic" "github.com/Axway/agent-sdk/pkg/util/log" @@ -39,7 +37,7 @@ func (a *GatewayClient) DiscoverAPIs() error { // As sample the implementation reads the swagger for musical-instrument from local directory swaggerSpec, err := a.getSpec() if err != nil { - log.Infof("Failed to load sample API specification from %s: %s ", a.cfg.SpecPath, err.Error()) + log.Infof("Failed to load sample API specification %s ", err.Error()) } externalAPI := ExternalAPI{ @@ -80,9 +78,6 @@ func (a *GatewayClient) buildServiceBody(externalAPI ExternalAPI) (apic.ServiceB } func (a *GatewayClient) getSpec() ([]byte, error) { - bytes, err := ioutil.ReadFile(a.cfg.SpecPath) - if err != nil { - return nil, err - } + var bytes []byte return bytes, nil } From 37a24f7ab4edc6ffbf9c2261173fffbc49f3a9a9 Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Wed, 27 Jan 2021 13:11:44 -0700 Subject: [PATCH 08/76] update --- default_kong_traceability_agent.yml | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/default_kong_traceability_agent.yml b/default_kong_traceability_agent.yml index a8701f4..3794dac 100644 --- a/default_kong_traceability_agent.yml +++ b/default_kong_traceability_agent.yml @@ -1,19 +1,18 @@ # this is a sample config file. Copy the content of this file to a new file named kong_traceability_agent.yml -kong_traceability_agent: - central: - environment: - mode: publishToEnvironment - organizationID: "" - platformURL: - team: "Default Team" - url: - auth: - clientID: - privateKey: - publicKey: - realm: Broker - timeout: 20s - url: https://login-preprod.axway.com/auth +central: + environment: + mode: publishToEnvironment + organizationID: "" + platformURL: + team: "Default Team" + url: + auth: + clientID: + privateKey: + publicKey: + realm: Broker + timeout: 20s + url: https://login-preprod.axway.com/auth # Condor Ingestion service output.traceability: From a046d5b9f2b83f3cae731966b9ce73ba3567ace2 Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Wed, 27 Jan 2021 16:13:50 -0700 Subject: [PATCH 09/76] add go-kong package to connect to gw --- go.mod | 1 + go.sum | 7 +++++ pkg/gateway/client.go | 61 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 56 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 5706245..28cb1f4 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/imdario/mergo v0.3.9 // indirect github.com/jcmturner/gofork v1.0.0 // indirect github.com/klauspost/cpuid v1.3.1 // indirect + github.com/kong/go-kong v0.15.0 github.com/kr/pretty v0.2.0 // indirect github.com/miekg/dns v1.1.29 // indirect github.com/mitchellh/hashstructure v1.0.0 // indirect diff --git a/go.sum b/go.sum index db7a881..1526062 100644 --- a/go.sum +++ b/go.sum @@ -92,6 +92,8 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= +github.com/blang/semver v0.0.0-20190414102917-ba2c2ddd8906/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver v3.1.0+incompatible h1:7hqmJYuaEK3qwVjWubYiht3j93YI0WQBuysxHIfUriU= github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bradleyfalzon/ghinstallation v1.1.0/go.mod h1:p7iD8KytOOKg2wCqbwvJlq4JGpYMjwjkiqdyUqOIHLI= github.com/bsm/sarama-cluster v2.1.14-0.20180625083203-7e67d87a6b3f+incompatible/go.mod h1:r7ao+4tTNXvWm+VRpRJchr2kQhqxgmAp2iEX5W96gMM= @@ -284,6 +286,7 @@ 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/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= github.com/google/go-github/v29 v29.0.2/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= @@ -392,6 +395,8 @@ github.com/klauspost/compress v1.8.2 h1:Bx0qjetmNjdFXASH02NSAREKpiaDwkO1DRZ3dV2K github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s= github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4= +github.com/kong/go-kong v0.15.0 h1:9Y+7iqh7/0z8/BppAaLEV7ueSSyqK6lJOHFvqJnSSqM= +github.com/kong/go-kong v0.15.0/go.mod h1:oF4kdI9l/a8ndDW2ayJA0yhDBpO8Qt2aLiJEv10hqnQ= 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 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= @@ -543,6 +548,8 @@ github.com/samuel/go-thrift v0.0.0-20140522043831-2187045faa54/go.mod h1:Vrkh1pn github.com/sanathkr/go-yaml v0.0.0-20170819195128-ed9d249f429b/go.mod h1:8458kAagoME2+LN5//WxE71ysZ3B7r22fdgb7qVmXSY= github.com/sanathkr/yaml v0.0.0-20170819201035-0056894fa522/go.mod h1:tQTYKOQgxoH3v6dEmdHiz4JG+nbxWwM5fgPQUpSZqVQ= github.com/sanathkr/yaml v1.0.1-0.20170819201035-0056894fa522/go.mod h1:tQTYKOQgxoH3v6dEmdHiz4JG+nbxWwM5fgPQUpSZqVQ= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shirou/gopsutil v2.19.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 24a2485..0a3a35a 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -1,25 +1,42 @@ package gateway import ( + "context" + "net/http" + "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/apic" "github.com/Axway/agent-sdk/pkg/util/log" config "github.com/Axway/agents-kong/pkg/config/discovery" + "github.com/kong/go-kong/kong" ) -// GatewayClient - Represents the Gateway client -type GatewayClient struct { - cfg *config.GatewayConfig +type Client struct { + cfg *config.GatewayConfig + kongClient *kong.Client } -// NewClient - Creates a new Gateway Client -func NewClient(gatewayCfg *config.GatewayConfig) (*GatewayClient, error) { - return &GatewayClient{ - cfg: gatewayCfg, +func NewClient(gatewayCfg *config.GatewayConfig) (*Client, error) { + clientBase := &http.Client{} + defaultTransport := http.DefaultTransport.(*http.Transport) + clientBase.Transport = defaultTransport + + headers := make(http.Header) + headers.Set("Kong-Admin-Token", gatewayCfg.Token) + client := kong.HTTPClientWithHeaders(clientBase, headers) + + kongClient, err := kong.NewClient(&gatewayCfg.AdminEndpoint, &client) + if err != nil { + return nil, err + } + kongClient.SetDebugMode(true) + + return &Client{ + cfg: gatewayCfg, + kongClient: kongClient, }, nil } -// ExternalAPI - Sample struct representing the API definition in API gateway type ExternalAPI struct { swaggerSpec []byte id string @@ -31,11 +48,13 @@ type ExternalAPI struct { } // DiscoverAPIs - Process the API discovery -func (a *GatewayClient) DiscoverAPIs() error { +func (gc *Client) DiscoverAPIs() error { + ctx := context.Background() + gc.GetAllServices(ctx) // Gateway specific implementation to get the details for discovered API goes here // Set the service definition // As sample the implementation reads the swagger for musical-instrument from local directory - swaggerSpec, err := a.getSpec() + swaggerSpec, err := gc.getSpec() if err != nil { log.Infof("Failed to load sample API specification %s ", err.Error()) } @@ -50,7 +69,7 @@ func (a *GatewayClient) DiscoverAPIs() error { swaggerSpec: swaggerSpec, } - serviceBody, err := a.buildServiceBody(externalAPI) + serviceBody, err := gc.buildServiceBody(externalAPI) if err != nil { return err } @@ -63,7 +82,7 @@ func (a *GatewayClient) DiscoverAPIs() error { } // buildServiceBody - creates the service definition -func (a *GatewayClient) buildServiceBody(externalAPI ExternalAPI) (apic.ServiceBody, error) { +func (gc *Client) buildServiceBody(externalAPI ExternalAPI) (apic.ServiceBody, error) { return apic.NewServiceBodyBuilder(). SetID(externalAPI.id). SetTitle(externalAPI.name). @@ -77,7 +96,23 @@ func (a *GatewayClient) buildServiceBody(externalAPI ExternalAPI) (apic.ServiceB Build() } -func (a *GatewayClient) getSpec() ([]byte, error) { +func (gc *Client) getSpec() ([]byte, error) { var bytes []byte return bytes, nil } + +func (gc *Client) GetService(ctx context.Context, service string) (*kong.Service, error) { + servicesClient := gc.kongClient.Services + return servicesClient.Get(ctx, &service) +} + +func (gc *Client) GetAllServices(ctx context.Context) ([]*kong.Service, error) { + servicesClient := gc.kongClient.Services + return servicesClient.ListAll(ctx) +} + +func (gc *Client) GetServiceRoutes(service string) { +} + +func (gc *Client) GetAllRoutes() { +} From fd5b0e890e22e9add9cfaae0a2471683cd82c1af Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Wed, 27 Jan 2021 17:31:32 -0700 Subject: [PATCH 10/76] init trace server --- pkg/server/traceability.go | 43 +++++++++++++++++++++++++++++++++ pkg/server/traceability_test.go | 7 ++++++ 2 files changed, 50 insertions(+) create mode 100644 pkg/server/traceability.go create mode 100644 pkg/server/traceability_test.go diff --git a/pkg/server/traceability.go b/pkg/server/traceability.go new file mode 100644 index 0000000..1af2828 --- /dev/null +++ b/pkg/server/traceability.go @@ -0,0 +1,43 @@ +package server + +import ( + "fmt" + "io/ioutil" + "net/http" + + log "github.com/Axway/agent-sdk/pkg/util/log" +) + +func NewTraceServer() { + http.HandleFunc("/logs", logHandler) + log.Info("Starting Kong Traceability Agent on port 8080") + err := http.ListenAndServe(":8080", nil) + if err != nil { + panic(err) + } +} + +func logHandler(w http.ResponseWriter, req *http.Request) { + if req.Method != http.MethodPost { + w.WriteHeader(405) + return + } + + // authenticate the request + + // Is it only json? + if req.Header.Get("Content-Type") != "application/json" { + w.WriteHeader(400) + return + } + + body, err := ioutil.ReadAll(req.Body) + if err != nil { + w.WriteHeader(500) + return + } + log.Info(string(body)) + + w.WriteHeader(200) + fmt.Fprint(w, "Kong Traceability Agent") +} diff --git a/pkg/server/traceability_test.go b/pkg/server/traceability_test.go new file mode 100644 index 0000000..9a0799b --- /dev/null +++ b/pkg/server/traceability_test.go @@ -0,0 +1,7 @@ +package server + +import "testing" + +func Test_NewServer(t *testing.T) { + NewTraceServer() +} From 4025839814ce582211f32809fee442b4df8c838f Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Thu, 28 Jan 2021 11:12:37 -0700 Subject: [PATCH 11/76] update --- cmd/main.go | 1 + default_kong_discovery_agent.yml | 1 - default_kong_traceability_agent.yml | 1 - pkg/cmd/discovery/discoveryCmd.go | 3 --- pkg/cmd/traceability/traceabilityCmd.go | 2 -- pkg/config/discovery/config.go | 1 - pkg/config/traceability/config.go | 1 - pkg/gateway/client.go | 11 ++--------- 8 files changed, 3 insertions(+), 18 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index da026db..1f6cd8c 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,6 +1,7 @@ package main import ( + _ "github.com/Axway/agent-sdk/pkg/traceability" "github.com/Axway/agents-kong/pkg/cmd" ) diff --git a/default_kong_discovery_agent.yml b/default_kong_discovery_agent.yml index a877381..28d87e6 100644 --- a/default_kong_discovery_agent.yml +++ b/default_kong_discovery_agent.yml @@ -23,6 +23,5 @@ log: kong: admin_endpoint: - proxy_endpoint: token: 1234 user: admin diff --git a/default_kong_traceability_agent.yml b/default_kong_traceability_agent.yml index 3794dac..866ecfb 100644 --- a/default_kong_traceability_agent.yml +++ b/default_kong_traceability_agent.yml @@ -44,6 +44,5 @@ logging: kong: admin_endpoint: - proxy_endpoint: token: 1234 user: admin \ No newline at end of file diff --git a/pkg/cmd/discovery/discoveryCmd.go b/pkg/cmd/discovery/discoveryCmd.go index d435897..357de3d 100644 --- a/pkg/cmd/discovery/discoveryCmd.go +++ b/pkg/cmd/discovery/discoveryCmd.go @@ -3,7 +3,6 @@ package discovery import ( corecmd "github.com/Axway/agent-sdk/pkg/cmd" corecfg "github.com/Axway/agent-sdk/pkg/config" - config "github.com/Axway/agents-kong/pkg/config/discovery" "github.com/Axway/agents-kong/pkg/gateway" ) @@ -27,7 +26,6 @@ func init() { rootProps.AddStringProperty("kong.user", "", "Kong Gateway admin user") rootProps.AddStringProperty("kong.token", "", "Token to authenticate with Kong Gateway") rootProps.AddStringProperty("kong.admin_endpoint", "", "The Kong Admin endpoint") - rootProps.AddStringProperty("kong.proxy_endpoint", "", "The Kong Proxy endpoint") } // Callback that agent will call to process the execution @@ -44,7 +42,6 @@ func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { // Parse the config from bound properties and setup gateway config gatewayConfig = &config.GatewayConfig{ AdminEndpoint: rootProps.StringPropertyValue("kong.admin_endpoint"), - ProxyEndpoint: rootProps.StringPropertyValue("kong.proxy_endpoint"), Token: rootProps.StringPropertyValue("kong.token"), User: rootProps.StringPropertyValue("kong.user"), } diff --git a/pkg/cmd/traceability/traceabilityCmd.go b/pkg/cmd/traceability/traceabilityCmd.go index c2220d9..f3276a7 100644 --- a/pkg/cmd/traceability/traceabilityCmd.go +++ b/pkg/cmd/traceability/traceabilityCmd.go @@ -38,7 +38,6 @@ func init() { rootProps.AddStringProperty("kong.user", "", "Kong Gateway admin user") rootProps.AddStringProperty("kong.token", "", "Token to authenticate with Kong Gateway") rootProps.AddStringProperty("kong.admin_endpoint", "", "The Kong Admin endpoint") - rootProps.AddStringProperty("kong.proxy_endpoint", "", "The Kong Proxy endpoint") } // Callback that agent will call to process the execution @@ -55,7 +54,6 @@ func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { // LogFile: rootProps.StringPropertyValue("gateway-section.logFile"), // ProcessOnInput: rootProps.BoolPropertyValue("gateway-section.processOnInput"), AdminEndpoint: rootProps.StringPropertyValue("kong.admin_endpoint"), - ProxyEndpoint: rootProps.StringPropertyValue("kong.proxy_endpoint"), Token: rootProps.StringPropertyValue("kong.token"), User: rootProps.StringPropertyValue("kong.user"), } diff --git a/pkg/config/discovery/config.go b/pkg/config/discovery/config.go index 1b8b653..44f69da 100644 --- a/pkg/config/discovery/config.go +++ b/pkg/config/discovery/config.go @@ -14,7 +14,6 @@ type AgentConfig struct { type GatewayConfig struct { corecfg.IConfigValidator AdminEndpoint string `config:"adminEndpoint"` - ProxyEndpoint string `config:"proxyEndpoint"` Token string `config:"token"` User string `config:"user"` } diff --git a/pkg/config/traceability/config.go b/pkg/config/traceability/config.go index fe7f54e..abe5eb1 100644 --- a/pkg/config/traceability/config.go +++ b/pkg/config/traceability/config.go @@ -18,7 +18,6 @@ type GatewayConfig struct { LogFile string `config:"logFile"` ProcessOnInput bool `config:"processOnInput"` AdminEndpoint string `config:"adminEndpoint"` - ProxyEndpoint string `config:"proxyEndpoint"` Token string `config:"token"` User string `config:"user"` } diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 0a3a35a..3e0f126 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -29,7 +29,7 @@ func NewClient(gatewayCfg *config.GatewayConfig) (*Client, error) { if err != nil { return nil, err } - kongClient.SetDebugMode(true) + // kongClient.SetDebugMode(true) return &Client{ cfg: gatewayCfg, @@ -97,8 +97,7 @@ func (gc *Client) buildServiceBody(externalAPI ExternalAPI) (apic.ServiceBody, e } func (gc *Client) getSpec() ([]byte, error) { - var bytes []byte - return bytes, nil + return []byte("{}"), nil } func (gc *Client) GetService(ctx context.Context, service string) (*kong.Service, error) { @@ -110,9 +109,3 @@ func (gc *Client) GetAllServices(ctx context.Context) ([]*kong.Service, error) { servicesClient := gc.kongClient.Services return servicesClient.ListAll(ctx) } - -func (gc *Client) GetServiceRoutes(service string) { -} - -func (gc *Client) GetAllRoutes() { -} From 7f847e3c148a82a150d1f082e0380951f6f691ad Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Fri, 29 Jan 2021 10:37:29 -0700 Subject: [PATCH 12/76] readme --- README.md | 52 ++++++++++++++++++++++++++++- default_kong_discovery_agent.yml | 6 ++-- default_kong_traceability_agent.yml | 12 +++---- 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 7a0089b..e6439bd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,54 @@ -# agents-kong +# Getting started + +To download the package dependencies run `make download` + +## Create an environment in Central + +Log into Amplify Central https://apicentral.axway.com +Navigate to the Topology page +Click the "Environment" button in the top right. +Select "Other" for the gateway type. +Provide a name and a title, such as "kong-gateway" and then hit "Save" in the top right. + +## Create a DOSA Account + +Create a public and private key pair locally on your computer. +Click the "Access" tab on the sidebar, which is the second to last tab. +Click on "Service Accounts". +Click the button in the top right that says "+ Service Account". +Name the account and provide the public key. + +## Find your Organization ID + +After making the environment click on your name in the top right. Select "Organization" from the dropdown. +You will see a field called "Organization ID". This will be needed to connect the agents to your org. + +## Create a Kong user + +Log into the kong manager. You will need to have a trial enterprise account. Ex: https://manager-radixlink2fbc76.kong-cloud.com/login +Click the Teams tab in the top navigation +Click the RBAC Users tab +Click the "Add New User" button +Provide a name for the user, and a value to use as a token, ex: 1234. +Click the Add/Edit Roles and add the "super-admin" role. + +## Fill out the environment variables + +Copy the content of `default_kong_discovery_agent.yml` to a new file named `kong_discovery_agent.yml` +Copy the content of `default_kong_traceability_agent.yml` to a new file named `kong_traceability_agent.yml` + +In each of the two config files for the agents provide the following variables for your config. +Provide the `environment`, `organizationID`, `platformURL`, `team`, `url`, `clientID`, `privateKey`, `publicKey` (provide the full file path to the keys). + +In the `kong_discovery_agent.yml` file provide the details of the kong user. `admin_endpoint`, `user`, `token` + +# Run the agents + +## Development + +In development you can run the agents by running `go run ./cmd/main.go`. You do not need to build the binary for agents on every change. + +## Build and run the binary To build the agents run `make build` diff --git a/default_kong_discovery_agent.yml b/default_kong_discovery_agent.yml index 28d87e6..96ad142 100644 --- a/default_kong_discovery_agent.yml +++ b/default_kong_discovery_agent.yml @@ -3,17 +3,17 @@ central: environment: mode: publishToEnvironment organizationID: "" - platformURL: + platformURL: https://platform.axway.com pollInterval: 20s team: "Default Team" - url: + url: https://apicentral.axway.com auth: clientID: privateKey: publicKey: realm: Broker timeout: 20s - url: https://login-preprod.axway.com/auth + url: https://login.axway.com/auth log: level: debug diff --git a/default_kong_traceability_agent.yml b/default_kong_traceability_agent.yml index 866ecfb..6947e0e 100644 --- a/default_kong_traceability_agent.yml +++ b/default_kong_traceability_agent.yml @@ -3,16 +3,17 @@ central: environment: mode: publishToEnvironment organizationID: "" - platformURL: + platformURL: https://platform.axway.com + pollInterval: 20s team: "Default Team" - url: + url: https://apicentral.axway.com auth: clientID: privateKey: publicKey: realm: Broker timeout: 20s - url: https://login-preprod.axway.com/auth + url: https://login.axway.com/auth # Condor Ingestion service output.traceability: @@ -41,8 +42,3 @@ logging: enabled: false to_stderr: true level: ${LOG_LEVEL:"info"} - -kong: - admin_endpoint: - token: 1234 - user: admin \ No newline at end of file From 5a57c594099a6f06b71b696bb8f22f426c53d0dc Mon Sep 17 00:00:00 2001 From: sagarkal Date: Thu, 4 Feb 2021 10:10:01 -0700 Subject: [PATCH 13/76] Changes for discovery, traceability and subscription (#4) Discovery, Subscriptions & Traceability --- .gitignore | 2 + Dockerfile | 38 ++ Makefile | 15 +- README.md | 6 +- Traceability-README.md | 31 ++ cmd/discovery/main.go | 16 + cmd/main.go | 10 - cmd/traceability/main.go | 16 + default_kong_discovery_agent.yml | 8 +- go.mod | 7 +- go.sum | 6 +- kong_traceability_agent.yml | 49 +++ pkg/beater/custom_log_filebeater.go | 92 ++-- pkg/cmd/discovery/discoveryCmd.go | 60 ++- pkg/cmd/root.go | 27 -- pkg/cmd/traceability/traceabilityCmd.go | 19 - pkg/config/discovery/config.go | 38 +- pkg/config/traceability/config.go | 23 +- pkg/gateway/cache.go | 57 +++ pkg/gateway/centralclient.go | 57 +++ pkg/gateway/client.go | 356 +++++++++++++--- pkg/gateway/definitions.go | 58 ++- pkg/gateway/eventmapper.go | 123 ------ pkg/gateway/logreader.go | 32 -- pkg/gateway/openapi.go | 32 ++ pkg/kong/definitions.go | 21 + pkg/kong/kongclient.go | 112 +++++ pkg/kong/plugins.go | 75 ++++ pkg/kong/plugins_test.go | 122 ++++++ pkg/kong/specmanager/devportal/devportal.go | 28 ++ pkg/kong/specmanager/localdir/localdir.go | 72 ++++ pkg/kong/specmanager/specmanager.go | 42 ++ pkg/processor/definitions.go | 85 ++++ pkg/processor/eventmapper.go | 162 +++++++ pkg/{gateway => processor}/eventprocessor.go | 49 +-- pkg/server/traceability.go | 43 -- pkg/server/traceability_test.go | 7 - pkg/subscription/apikey.go | 12 + pkg/subscription/apikey/apikey.go | 206 +++++++++ pkg/subscription/package.go | 3 + pkg/subscription/subscription_test.go | 427 +++++++++++++++++++ pkg/subscription/subscriptionmanager.go | 221 ++++++++++ png/KongAgentHTTP.png | Bin 0 -> 106465 bytes specs/petstore.json | 222 ++++++++++ 44 files changed, 2595 insertions(+), 492 deletions(-) create mode 100644 Dockerfile create mode 100644 Traceability-README.md create mode 100644 cmd/discovery/main.go delete mode 100644 cmd/main.go create mode 100644 cmd/traceability/main.go create mode 100644 kong_traceability_agent.yml delete mode 100644 pkg/cmd/root.go create mode 100644 pkg/gateway/cache.go create mode 100644 pkg/gateway/centralclient.go delete mode 100644 pkg/gateway/eventmapper.go delete mode 100644 pkg/gateway/logreader.go create mode 100644 pkg/gateway/openapi.go create mode 100644 pkg/kong/definitions.go create mode 100644 pkg/kong/kongclient.go create mode 100644 pkg/kong/plugins.go create mode 100644 pkg/kong/plugins_test.go create mode 100644 pkg/kong/specmanager/devportal/devportal.go create mode 100644 pkg/kong/specmanager/localdir/localdir.go create mode 100644 pkg/kong/specmanager/specmanager.go create mode 100644 pkg/processor/definitions.go create mode 100644 pkg/processor/eventmapper.go rename pkg/{gateway => processor}/eventprocessor.go (61%) delete mode 100644 pkg/server/traceability.go delete mode 100644 pkg/server/traceability_test.go create mode 100644 pkg/subscription/apikey.go create mode 100644 pkg/subscription/apikey/apikey.go create mode 100644 pkg/subscription/package.go create mode 100644 pkg/subscription/subscription_test.go create mode 100644 pkg/subscription/subscriptionmanager.go create mode 100644 png/KongAgentHTTP.png create mode 100644 specs/petstore.json diff --git a/.gitignore b/.gitignore index c891cc8..1c755b5 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ bin/ kong_discovery_agent.yml kong_traceability_agent.yml + +specs/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..57fc715 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,38 @@ +FROM beano.swf-artifactory.lab.phx.axway.int/beano-alpine-base:latest as builder + +RUN mkdir -p /go/src/git.ecd.axway.org/apigov/kong_traceability_agent + +WORKDIR /go/src/git.ecd.axway.org/apigov/kong_traceability_agent + +COPY . . + +RUN make build + +RUN ls -l bin/ + +# Create non-root user +RUN addgroup -g 2500 axway && adduser -u 2500 -D -G axway axway +RUN chown -R axway:axway /go/src/git.ecd.axway.org/apigov/kong_traceability_agent/bin/kong_traceability_agent +USER axway + +# alpine 3.12.0 +FROM docker.io/alpine@sha256:a15790640a6690aa1730c38cf0a440e2aa44aaca9b0e8931a9f2b0d7cc90fd65 + +COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt +COPY --from=builder /etc/passwd /etc/passwd +COPY --from=builder /go/src/git.ecd.axway.org/apigov/kong_traceability_agent/kong_traceability_agent.yml /kong_traceability_agent.yml +COPY --from=builder /go/src/git.ecd.axway.org/apigov/kong_traceability_agent/bin/kong_traceability_agent /kong_traceability_agent +COPY --from=builder /go/src/git.ecd.axway.org/apigov/kong_traceability_agent/private_key.pem private_key.pem +COPY --from=builder /go/src/git.ecd.axway.org/apigov/kong_traceability_agent/public_key.pem public_key.pem + +RUN mkdir /keys /data && \ + chown -R axway /data /keys /kong_traceability_agent.yml && \ + chmod go-w /kong_traceability_agent.yml + +RUN find / -perm /6000 -type f -exec chmod a-s {} \; || true + +USER axway + +VOLUME ["/keys"] + +ENTRYPOINT ["/kong_traceability_agent"] \ No newline at end of file diff --git a/Makefile b/Makefile index aeffdfd..61d246d 100644 --- a/Makefile +++ b/Makefile @@ -10,14 +10,17 @@ tidy: go.mod download: tidy @go mod download -build: - @go build -o bin/agents-kong ./cmd/main.go +build-disc: + @go build -o bin/discovery ./cmd/discovery/main.go -run-discovery: - ./bin/agents-kong apic_discovery_agent +build-trace: + @go build -o bin/traceability ./cmd/traceability/main.go -run-traceability: - ./bin/agents-kong apic_traceability_agent +run-disc: + ./bin/discovery + +run-trace: + ./bin/traceability lint: @golangci-lint run -v diff --git a/README.md b/README.md index e6439bd..ffccd22 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Provide a name and a title, such as "kong-gateway" and then hit "Save" in the to ## Create a DOSA Account Create a public and private key pair locally on your computer. -Click the "Access" tab on the sidebar, which is the second to last tab. +In Central, click the "Access" tab on the sidebar, which is the second to last tab. Click on "Service Accounts". Click the button in the top right that says "+ Service Account". Name the account and provide the public key. @@ -46,7 +46,9 @@ In the `kong_discovery_agent.yml` file provide the details of the kong user. `ad ## Development -In development you can run the agents by running `go run ./cmd/main.go`. You do not need to build the binary for agents on every change. +Each agent is built and run independently + +In development you can run an agent by running `go run ./cmd/discovery/discovery.go` or `go run ./cmd/discovery/traceability.go`. You do not need to build the binary for agents on every change. ## Build and run the binary diff --git a/Traceability-README.md b/Traceability-README.md new file mode 100644 index 0000000..3a6eb33 --- /dev/null +++ b/Traceability-README.md @@ -0,0 +1,31 @@ +# Kong Traceability agent + +## Overview +Kong Traceability agent does these tasks: +* Runs an HTTP Server exposing an endpoint that serves as the target for Kong's [HTTP Log Plugin](https://docs.konghq.com/hub/kong-inc/http-log/) +* Processes the request logs as they are sent by the HTTP Log plugin and builds transaction summary and transaction leg event in the format expected by Central's API Observer +* Uses libbeat to publish the events to Condor + +## Prerequisites +Kong Traceability agent requires **global deployment** of the below plugins in order to generate transaction summary and transaction leg event for all Kong's proxies +* [Correlation ID Plugin](https://docs.konghq.com/hub/kong-inc/correlation-id/) used for transaction ID +* [HTTP Log Plugin](https://docs.konghq.com/hub/kong-inc/http-log/) used to get the request logs associated with Kong proxy invocation + +## Build + +In order to build, run +```shell +make build-trace +``` + +## Configuration + +Configuration can be provided via kong_traceability_agent.yml under **traceability** folder + +## Run + +In order to run, make sure you are in **traceability** folder and run +```shell +make run +``` + diff --git a/cmd/discovery/main.go b/cmd/discovery/main.go new file mode 100644 index 0000000..475fb6f --- /dev/null +++ b/cmd/discovery/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "fmt" + "os" + + "github.com/Axway/agents-kong/pkg/cmd/discovery" +) + +func main() { + + if err := discovery.DiscoveryCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/cmd/main.go b/cmd/main.go deleted file mode 100644 index 1f6cd8c..0000000 --- a/cmd/main.go +++ /dev/null @@ -1,10 +0,0 @@ -package main - -import ( - _ "github.com/Axway/agent-sdk/pkg/traceability" - "github.com/Axway/agents-kong/pkg/cmd" -) - -func main() { - cmd.Execute() -} diff --git a/cmd/traceability/main.go b/cmd/traceability/main.go new file mode 100644 index 0000000..c957c5f --- /dev/null +++ b/cmd/traceability/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "fmt" + "os" + + _ "github.com/Axway/agent-sdk/pkg/traceability" + "github.com/Axway/agents-kong/pkg/cmd/traceability" +) + +func main() { + if err := traceability.TraceCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/default_kong_discovery_agent.yml b/default_kong_discovery_agent.yml index 96ad142..9d1151a 100644 --- a/default_kong_discovery_agent.yml +++ b/default_kong_discovery_agent.yml @@ -1,7 +1,7 @@ # this is a sample config file. Copy the content of this file to a new file named kong_discovery_agent.yml central: environment: - mode: publishToEnvironment + mode: publishToEnvironmentAndCatalog organizationID: "" platformURL: https://platform.axway.com pollInterval: 20s @@ -25,3 +25,9 @@ kong: admin_endpoint: token: 1234 user: admin + proxy_endpoint: + proxy_endpoint_protocols: + http: 80 + https: 443 + spec_dev_portal_enabled: + spec_home_path: diff --git a/go.mod b/go.mod index 28cb1f4..f810451 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Axway/agents-kong go 1.13 require ( - github.com/Axway/agent-sdk v0.0.19-0.20210126163226-3d297ae76e96 + github.com/Axway/agent-sdk v0.0.20-0.20210204011617-097b5510cacd github.com/Shopify/sarama v1.26.4 // indirect github.com/docker/docker v1.13.1 // indirect github.com/dustin/go-humanize v1.0.0 // indirect @@ -22,15 +22,15 @@ require ( github.com/mitchellh/hashstructure v1.0.0 // indirect github.com/pelletier/go-toml v1.8.0 // indirect github.com/pierrec/lz4 v2.5.2+incompatible // indirect + github.com/sirupsen/logrus v1.6.0 github.com/spf13/afero v1.3.0 // indirect github.com/spf13/cast v1.3.1 // indirect - github.com/spf13/cobra v1.0.0 + github.com/tidwall/gjson v1.6.8 gopkg.in/ini.v1 v1.57.0 // indirect gopkg.in/jcmturner/gokrb5.v7 v7.5.0 // indirect ) replace ( - github.com/Azure/go-autorest => github.com/Azure/go-autorest v12.2.0+incompatible github.com/Shopify/sarama => github.com/elastic/sarama v0.0.0-20191122160421-355d120d0970 github.com/docker/docker => github.com/docker/engine v17.12.0-ce-rc1.0.20190717161051-705d9623b7c1+incompatible github.com/docker/go-plugins-helpers => github.com/elastic/go-plugins-helpers v0.0.0-20200207104224-bdf17607b79f @@ -39,7 +39,6 @@ replace ( github.com/fsnotify/fsnotify => github.com/adriansr/fsnotify v0.0.0-20180417234312-c9bbe1f46f1d github.com/google/gopacket => github.com/adriansr/gopacket v1.1.18-0.20200327165309-dd62abfa8a41 github.com/insomniacslk/dhcp => github.com/elastic/dhcp v0.0.0-20200227161230-57ec251c7eb3 // indirect - github.com/tonistiigi/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c k8s.io/api => k8s.io/api v0.17.0 k8s.io/apimachinery => k8s.io/apimachinery v0.17.0 k8s.io/client-go => k8s.io/client-go v0.17.0 diff --git a/go.sum b/go.sum index 1526062..61aa0b5 100644 --- a/go.sum +++ b/go.sum @@ -19,8 +19,8 @@ code.cloudfoundry.org/go-loggregator v7.4.0+incompatible/go.mod h1:KPBTRqj+y738N code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:sk5LnIjB/nIEU7yP5sDQExVm62wu0pBh3yrElngUisI= code.cloudfoundry.org/rfc5424 v0.0.0-20180905210152-236a6d29298a/go.mod h1:tkZo8GtzBjySJ7USvxm4E36lNQw1D3xM6oKHGqdaAJ4= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Axway/agent-sdk v0.0.19-0.20210126163226-3d297ae76e96 h1:w99KVTrHHFFT8f9Ej0OcnPAKyWITMCxjfV4DsU2IfKA= -github.com/Axway/agent-sdk v0.0.19-0.20210126163226-3d297ae76e96/go.mod h1:fOaWmFFg1eDheNJZNe2+T/jRwfSm8AWcap1p+ytBv8I= +github.com/Axway/agent-sdk v0.0.20-0.20210204011617-097b5510cacd h1:SaZIGyMcqhrOIAoLOiPRZDrwjSyLsIcJuMuvZQn6dbQ= +github.com/Axway/agent-sdk v0.0.20-0.20210204011617-097b5510cacd/go.mod h1:fOaWmFFg1eDheNJZNe2+T/jRwfSm8AWcap1p+ytBv8I= github.com/Azure/azure-amqp-common-go/v3 v3.0.0/go.mod h1:SY08giD/XbhTz07tJdpw1SoxQXHPN30+DI3Z04SYqyg= github.com/Azure/azure-event-hubs-go/v3 v3.1.2/go.mod h1:hR40byNJjKkS74+3RhloPQ8sJ8zFQeJ920Uk3oYY0+k= github.com/Azure/azure-pipeline-go v0.1.8/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg= @@ -605,6 +605,8 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tidwall/gjson v1.6.7 h1:Mb1M9HZCRWEcXQ8ieJo7auYyyiSux6w9XN3AdTpxJrE= github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= +github.com/tidwall/gjson v1.6.8 h1:CTmXMClGYPAmln7652e69B7OLXfTi5ABcPPwjIWUv7w= +github.com/tidwall/gjson v1.6.8/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE= github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU= diff --git a/kong_traceability_agent.yml b/kong_traceability_agent.yml new file mode 100644 index 0000000..4c75dfd --- /dev/null +++ b/kong_traceability_agent.yml @@ -0,0 +1,49 @@ +kong_traceability_agent: + central: + environment: kong-traceability-test + organizationID: 251204211014979 + platformURL: https://platform.axway.com + pollInterval: 20s + team: "Default Team" + url: https://apicentral.axway.com + auth: + clientID: DOSA_9f07ebffe9ab48cc8f8c7206f0fbc06b + privateKey: private_key.pem + publicKey: public_key.pem + realm: Broker + timeout: 20s + url: https://login.axway.com/auth + ssl: + minVersion: ${CENTRAL_SSL_MINVERSION:"TLS1.2"} + maxVersion: ${CENTRAL_SSL_MAXVERSION:"TLS1.3"} + nextProtos: ${CENTRAL_SSL_NEXTPROTOS:[]} + cipherSuites: ${CENTRAL_SSL_CIPHERSUITES:["ECDHE-ECDSA-AES-256-GCM-SHA384", "ECDHE-RSA-AES-256-GCM-SHA384", "ECDHE-ECDSA-CHACHA20-POLY1305", "ECDHE-RSA-CHACHA20-POLY1305", "ECDHE-ECDSA-AES-128-GCM-SHA256", "ECDHE-RSA-AES-128-GCM-SHA256", "ECDHE-ECDSA-AES-128-CBC-SHA256", "ECDHE-RSA-AES-128-CBC-SHA256"]} + insecureSkipVerify: ${CENTRAL_SSL_INSECURESKIPVERIFY:false} + +# Condor Ingestion service +output.traceability: + compression_level: ${TRACEABILITY_COMPRESSIONLEVEL:3} + enabled: true + hosts: + - ${TRACEABILITY_HOST:"ingestion-lumberjack.datasearch.axway.com:453"} + protocol: ${TRACEABILITY_PROTOCOL:"tcp"} + ssl: + enabled: true + verification_mode: full + cipher_suites: + - "ECDHE-ECDSA-AES-128-GCM-SHA256" + - "ECDHE-ECDSA-AES-256-GCM-SHA384" + - "ECDHE-ECDSA-CHACHA20-POLY1305" + - "ECDHE-RSA-AES-128-CBC-SHA256" + - "ECDHE-RSA-AES-128-GCM-SHA256" + - "ECDHE-RSA-AES-256-GCM-SHA384" + - "ECDHE-RSA-CHACHA20-POLY1205" + worker: 1 + pipelining: 0 + proxy_url: ${TRACEABILITY_PROXYURL:""} + +logging: + metrics: + enabled: false + to_stderr: true + level: ${LOG_LEVEL:"debug"} diff --git a/pkg/beater/custom_log_filebeater.go b/pkg/beater/custom_log_filebeater.go index 5bf89cb..be6a9ca 100644 --- a/pkg/beater/custom_log_filebeater.go +++ b/pkg/beater/custom_log_filebeater.go @@ -1,47 +1,35 @@ package beater import ( - "github.com/Axway/agent-sdk/pkg/traceability" + "fmt" + "io/ioutil" + "log" + "net/http" + + "github.com/Axway/agents-kong/pkg/processor" + agentErrors "github.com/Axway/agent-sdk/pkg/util/errors" hc "github.com/Axway/agent-sdk/pkg/util/healthcheck" - "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/logp" - - config "github.com/Axway/agents-kong/pkg/config/traceability" - "github.com/Axway/agents-kong/pkg/gateway" ) -// customLogBeater configuration. type customLogBeater struct { done chan struct{} - logReader *gateway.LogReader - eventProcessor *gateway.EventProcessor + eventProcessor *processor.EventProcessor client beat.Client eventChannel chan string } -var bt *customLogBeater -var gatewayConfig *config.GatewayConfig - -// New creates an instance of aws_apigw_traceability_agent. -func New(b *beat.Beat, cfg *common.Config) (beat.Beater, error) { +// New creates an instance of kong_traceability_agent. +func New(*beat.Beat, *common.Config) (beat.Beater, error) { bt := &customLogBeater{ done: make(chan struct{}), eventChannel: make(chan string), } - var err error - bt.logReader, err = gateway.NewLogReader(gatewayConfig, bt.eventChannel) - bt.eventProcessor = gateway.NewEventProcessor(gatewayConfig) - if err != nil { - return nil, err - } - - if !gatewayConfig.ProcessOnInput { - traceability.SetOutputEventProcessor(bt.eventProcessor) - } + bt.eventProcessor = processor.NewEventProcessor() // Validate that all necessary services are up and running. If not, return error if hc.RunChecks() != hc.OK { @@ -51,14 +39,9 @@ func New(b *beat.Beat, cfg *common.Config) (beat.Beater, error) { return bt, nil } -// SetGatewayConfig - set parsed gateway config -func SetGatewayConfig(gatewayCfg *config.GatewayConfig) { - gatewayConfig = gatewayCfg -} - -// Run starts awsApigwTraceabilityAgent. +// Run starts kong_traceability_agent. func (bt *customLogBeater) Run(b *beat.Beat) error { - logp.Info("apic_traceability_agent is running! Hit CTRL-C to stop it.") + logp.Info("kong_traceability_agent is running! Hit CTRL-C to stop it.") var err error bt.client, err = b.Publisher.Connect() @@ -66,32 +49,49 @@ func (bt *customLogBeater) Run(b *beat.Beat) error { return err } - bt.logReader.Start() + http.HandleFunc("/requestlogs", func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + + body, err := ioutil.ReadAll(r.Body) + defer r.Body.Close() + + if err != nil { + fmt.Errorf("Error while reading request body: %s", err) + } + + w.WriteHeader(200) + bt.processAndDispatchEvent(string(body)) + }) + + /* Start a new HTTP server in a separate Go routine that will be the target + for the HTTP Log plugin. It should write events it gets to eventChannel */ + go func() { + if err := http.ListenAndServe(":9000", nil); err != nil { + log.Fatalf("Unable to start the HTTP Server: %s", err) + } + log.Print("Started HTTP server on port 9000 to receive request logs") + }() for { select { case <-bt.done: return nil - case eventData := <-bt.eventChannel: - if gatewayConfig.ProcessOnInput { - eventsToPublish := bt.eventProcessor.ProcessRaw([]byte(eventData)) - if eventsToPublish != nil { - bt.client.PublishAll(eventsToPublish) - } - } else { - eventToPublish := beat.Event{ - Fields: common.MapStr{ - "message": eventData, - }, - } - bt.client.Publish(eventToPublish) - } } } } -// Stop stops customLogTraceabilityAgent. +// Stop stops kong_traceability_agent. func (bt *customLogBeater) Stop() { bt.client.Close() close(bt.done) } + +func (bt *customLogBeater) processAndDispatchEvent(logEvent string) { + eventsToPublish := bt.eventProcessor.ProcessRaw([]byte(logEvent)) + if eventsToPublish != nil { + bt.client.PublishAll(eventsToPublish) + } +} diff --git a/pkg/cmd/discovery/discoveryCmd.go b/pkg/cmd/discovery/discoveryCmd.go index 357de3d..f07fa98 100644 --- a/pkg/cmd/discovery/discoveryCmd.go +++ b/pkg/cmd/discovery/discoveryCmd.go @@ -1,14 +1,17 @@ package discovery import ( + "time" + corecmd "github.com/Axway/agent-sdk/pkg/cmd" corecfg "github.com/Axway/agent-sdk/pkg/config" + "github.com/Axway/agent-sdk/pkg/util/log" config "github.com/Axway/agents-kong/pkg/config/discovery" "github.com/Axway/agents-kong/pkg/gateway" ) var DiscoveryCmd corecmd.AgentRootCmd -var gatewayConfig *config.GatewayConfig +var agentConfig config.AgentConfig func init() { // Create new root command with callbacks to initialize the agent config and command execution. @@ -25,13 +28,37 @@ func init() { rootProps := DiscoveryCmd.GetProperties() rootProps.AddStringProperty("kong.user", "", "Kong Gateway admin user") rootProps.AddStringProperty("kong.token", "", "Token to authenticate with Kong Gateway") - rootProps.AddStringProperty("kong.admin_endpoint", "", "The Kong Admin endpoint") + rootProps.AddStringProperty("kong.admin_endpoint", "", "The Kong admin endpoint") + rootProps.AddStringProperty("kong.proxy_endpoint", "", "The Kong proxy endpoint") + rootProps.AddIntProperty("kong.proxy_endpoint_protocols.http", 80, "The Kong proxy http port") + rootProps.AddIntProperty("kong.proxy_endpoint_protocols.https", 443, "The Kong proxy https port") } // Callback that agent will call to process the execution func run() error { - gatewayClient, err := gateway.NewClient(gatewayConfig) - err = gatewayClient.DiscoverAPIs() + var err error + var stopChan chan struct{} + stopChan = make(chan struct{}) + + gatewayClient, err := gateway.NewClient(agentConfig) + go func() { + for { + err = gatewayClient.DiscoverAPIs() + if err != nil { + log.Error("error in processing: %s", err) + stopChan <- struct{}{} + } + log.Infof("next poll in %s", agentConfig.CentralCfg.GetPollInterval()) + time.Sleep(agentConfig.CentralCfg.GetPollInterval()) + } + }() + + select { + case <-stopChan: + log.Info("Received signal to stop processing") + break + } + return err } @@ -39,21 +66,26 @@ func run() error { // and passed to the callback allowing the agent code to access the central config func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { rootProps := DiscoveryCmd.GetProperties() + // Parse the config from bound properties and setup gateway config - gatewayConfig = &config.GatewayConfig{ - AdminEndpoint: rootProps.StringPropertyValue("kong.admin_endpoint"), - Token: rootProps.StringPropertyValue("kong.token"), - User: rootProps.StringPropertyValue("kong.user"), + gatewayConfig := &config.KongGatewayConfig{ + AdminEndpoint: rootProps.StringPropertyValue("kong.admin_endpoint"), + Token: rootProps.StringPropertyValue("kong.token"), + User: rootProps.StringPropertyValue("kong.user"), + ProxyEndpoint: rootProps.StringPropertyValue("kong.proxy_endpoint"), + ProxyHttpPort: rootProps.IntPropertyValue("kong.proxy_endpoint_protocols.http"), + ProxyHttpsPort: rootProps.IntPropertyValue("kong.proxy_endpoint_protocols.https"), + SpecHomePath: rootProps.StringPropertyValue("kong.spec_home_path"), + SpecDevPortalEnabled: rootProps.BoolPropertyValue("kong.spec_dev_portal_enabled"), } - agentConfig := config.AgentConfig{ - CentralCfg: centralConfig, - GatewayCfg: gatewayConfig, + agentConfig = config.AgentConfig{ + CentralCfg: centralConfig, + KongGatewayCfg: gatewayConfig, } return agentConfig, nil } -// GetAgentConfig - Returns the agent config -func GetAgentConfig() *config.GatewayConfig { - return gatewayConfig +func GetAgentConfig() config.AgentConfig { + return agentConfig } diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go deleted file mode 100644 index d268368..0000000 --- a/pkg/cmd/root.go +++ /dev/null @@ -1,27 +0,0 @@ -package cmd - -import ( - "os" - - "github.com/Axway/agents-kong/pkg/cmd/discovery" - "github.com/Axway/agents-kong/pkg/cmd/traceability" - - "github.com/spf13/cobra" -) - -// RootCmd is the root -var RootCmd = &cobra.Command{ - Use: "kong-agent", - Short: "Kong Discovery & Traceability Agent", -} - -func Execute() { - if err := RootCmd.Execute(); err != nil { - os.Exit(1) - } -} - -func init() { - RootCmd.AddCommand(discovery.DiscoveryCmd.RootCmd()) - RootCmd.AddCommand(traceability.TraceCmd.RootCmd()) -} diff --git a/pkg/cmd/traceability/traceabilityCmd.go b/pkg/cmd/traceability/traceabilityCmd.go index f3276a7..03ba756 100644 --- a/pkg/cmd/traceability/traceabilityCmd.go +++ b/pkg/cmd/traceability/traceabilityCmd.go @@ -31,16 +31,8 @@ func init() { run, corecfg.TraceabilityAgent, ) - - // Get the root command properties and bind the config property in YAML definition - - rootProps := TraceCmd.GetProperties() - rootProps.AddStringProperty("kong.user", "", "Kong Gateway admin user") - rootProps.AddStringProperty("kong.token", "", "Token to authenticate with Kong Gateway") - rootProps.AddStringProperty("kong.admin_endpoint", "", "The Kong Admin endpoint") } -// Callback that agent will call to process the execution func run() error { return beatCmd.Execute() } @@ -48,21 +40,10 @@ func run() error { // Callback that agent will call to initialize the config. CentralConfig is parsed by Agent SDK // and passed to the callback allowing the agent code to access the central config func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { - rootProps := TraceCmd.GetProperties() - // Parse the config from bound properties and setup gateway config - gatewayConfig := &config.GatewayConfig{ - // LogFile: rootProps.StringPropertyValue("gateway-section.logFile"), - // ProcessOnInput: rootProps.BoolPropertyValue("gateway-section.processOnInput"), - AdminEndpoint: rootProps.StringPropertyValue("kong.admin_endpoint"), - Token: rootProps.StringPropertyValue("kong.token"), - User: rootProps.StringPropertyValue("kong.user"), - } agentConfig := &config.AgentConfig{ CentralCfg: centralConfig, - GatewayCfg: gatewayConfig, } - beater.SetGatewayConfig(gatewayConfig) return agentConfig, nil } diff --git a/pkg/config/discovery/config.go b/pkg/config/discovery/config.go index 44f69da..de87745 100644 --- a/pkg/config/discovery/config.go +++ b/pkg/config/discovery/config.go @@ -1,24 +1,46 @@ package config import ( + "fmt" + corecfg "github.com/Axway/agent-sdk/pkg/config" ) // AgentConfig - represents the config for agent type AgentConfig struct { - CentralCfg corecfg.CentralConfig `config:"central"` - GatewayCfg *GatewayConfig `config:"kong"` + CentralCfg corecfg.CentralConfig `config:"central"` + KongGatewayCfg *KongGatewayConfig `config:"kong"` } -// GatewayConfig - represents the config for gateway -type GatewayConfig struct { +// KongGatewayConfig - represents the config for gateway +type KongGatewayConfig struct { corecfg.IConfigValidator - AdminEndpoint string `config:"adminEndpoint"` - Token string `config:"token"` - User string `config:"user"` + AdminEndpoint string `config:"adminEndpoint"` + Token string `config:"token"` + User string `config:"user"` + ProxyEndpoint string `config:"proxyEndpoint"` + ProxyHttpPort int `config:"proxyHttpPort"` + ProxyHttpsPort int `config:"proxyHttpsPort"` + SpecHomePath string `config:"specHomePath"` + SpecDevPortalEnabled bool `config:"specDevPortalEnabled"` } // ValidateCfg - Validates the gateway config -func (c *GatewayConfig) ValidateCfg() (err error) { +func (c *KongGatewayConfig) ValidateCfg() (err error) { + if c.Token == "" { + return fmt.Errorf("error: token is required") + } + if c.AdminEndpoint == "" { + return fmt.Errorf("error: admin_endpoint is required") + } + if c.ProxyEndpoint == "" { + return fmt.Errorf("error: proxy_endpoint is required") + } + if c.ProxyHttpPort == 0 || c.ProxyHttpsPort == 0 { + return fmt.Errorf("error: proxy_endpoint_protocols requires at least one value of either http or https") + } + if c.User == "" { + return fmt.Errorf("error: user is required") + } return } diff --git a/pkg/config/traceability/config.go b/pkg/config/traceability/config.go index abe5eb1..778db50 100644 --- a/pkg/config/traceability/config.go +++ b/pkg/config/traceability/config.go @@ -1,31 +1,10 @@ -package config +package traceability import ( - "errors" - corecfg "github.com/Axway/agent-sdk/pkg/config" ) // AgentConfig - represents the config for agent type AgentConfig struct { CentralCfg corecfg.CentralConfig `config:"central"` - GatewayCfg *GatewayConfig `config:"kong"` -} - -// GatewayConfig - represents the config for gateway -type GatewayConfig struct { - corecfg.IConfigValidator - LogFile string `config:"logFile"` - ProcessOnInput bool `config:"processOnInput"` - AdminEndpoint string `config:"adminEndpoint"` - Token string `config:"token"` - User string `config:"user"` -} - -// ValidateCfg - Validates the gateway config -func (c *GatewayConfig) ValidateCfg() (err error) { - if c.LogFile == "" { - return errors.New("Invalid gateway configuration: logFile is not configured") - } - return } diff --git a/pkg/gateway/cache.go b/pkg/gateway/cache.go new file mode 100644 index 0000000..9770f37 --- /dev/null +++ b/pkg/gateway/cache.go @@ -0,0 +1,57 @@ +package gateway + +import ( + "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" + "github.com/Axway/agent-sdk/pkg/cache" + "github.com/Axway/agent-sdk/pkg/util/log" +) + +// If the item is cached, return true +func setCachedService(kongServiceId string, kongServiceName string, hash string, centralName string) bool { + specCache := cache.GetCache() + item, err := specCache.Get(kongServiceId) + // if there is an error, then the item is not in the cache + if err != nil { + cachedService := CachedService{ + kongServiceId: kongServiceId, + kongServiceName: kongServiceName, + hash: hash, + centralName: centralName, + } + specCache.Set(kongServiceId, cachedService) + return false + } + + if item != nil { + if cachedService, ok := item.(CachedService); ok { + if cachedService.kongServiceId == kongServiceId && cachedService.hash == hash { + cachedService.centralName = centralName + cachedService.kongServiceName = kongServiceName + specCache.Set(kongServiceId, cachedService) + return true + } else { + cachedService.kongServiceName = kongServiceName + cachedService.hash = hash + specCache.Set(kongServiceId, cachedService) + log.Infof("adding to the cache: '%s'. centralName: '%s'", kongServiceName, centralName) + } + } + } + return false +} + +func initCache(centralAPIServices []*v1alpha1.APIService) { + clearCache() + log.Info("Init the cache") + for _, apiSvc := range centralAPIServices { + setCachedService(apiSvc.Attributes[externalAPIID], apiSvc.Title, apiSvc.Attributes[kongHash], apiSvc.Name) + } +} + +func clearCache() { + log.Info("Cache cleared") + cache := cache.GetCache() + for _, key := range cache.GetKeys() { + cache.Delete(key) + } +} diff --git a/pkg/gateway/centralclient.go b/pkg/gateway/centralclient.go new file mode 100644 index 0000000..2de31cb --- /dev/null +++ b/pkg/gateway/centralclient.go @@ -0,0 +1,57 @@ +package gateway + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" + corecfg "github.com/Axway/agent-sdk/pkg/config" + "github.com/Axway/agent-sdk/pkg/util/log" +) + +type CentralAPIClient interface { + ExecuteAPI(method, endpoint string, queryParam map[string]string, buffer []byte) ([]byte, error) +} + +type CentralClient struct { + client CentralAPIClient + envName string + apiServerHost string +} + +func NewCentralClient(client CentralAPIClient, config corecfg.CentralConfig) CentralClient { + return CentralClient{ + client: client, + envName: config.GetEnvironmentName(), + apiServerHost: config.GetAPIServerURL(), + } +} + +func (cc *CentralClient) execute(method, endpoint string, queryParam map[string]string, buffer []byte) ([]byte, error) { + host := cc.apiServerHost + cc.envName + endpoint + log.Infof("sending %s request: %s", method, host) + return cc.client.ExecuteAPI(method, host, queryParam, buffer) +} + +func (cc *CentralClient) fetchCentralAPIServices(queryParam map[string]string) ([]*v1alpha1.APIService, error) { + data, err := cc.execute(http.MethodGet, "/apiservices", queryParam, nil) + if err != nil { + return nil, fmt.Errorf("failed to get apiservices: %s", err) + } + + var centralAPIServices []*v1alpha1.APIService + err = json.Unmarshal(data, ¢ralAPIServices) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal apiservices: %s", err) + } + return centralAPIServices, nil +} + +func (cc *CentralClient) deleteCentralAPIService(cachedService CachedService) error { + // TODO: ExecuteAPI only returns a success when status code is 200 + cc.execute(http.MethodDelete, "/apiservices/"+cachedService.centralName, nil, nil) + + log.Infof("service removed: %s", cachedService.kongServiceName) + return nil +} diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 3e0f126..3c034fe 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -2,110 +2,334 @@ package gateway import ( "context" + "fmt" "net/http" + "sync" + + "github.com/Axway/agents-kong/pkg/kong/specmanager" + "github.com/Axway/agents-kong/pkg/kong/specmanager/devportal" + "github.com/Axway/agents-kong/pkg/kong/specmanager/localdir" + + "github.com/sirupsen/logrus" "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/apic" + "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" + "github.com/Axway/agent-sdk/pkg/cache" + + "github.com/Axway/agent-sdk/pkg/util" "github.com/Axway/agent-sdk/pkg/util/log" config "github.com/Axway/agents-kong/pkg/config/discovery" - "github.com/kong/go-kong/kong" + kutil "github.com/Axway/agents-kong/pkg/kong" + "github.com/Axway/agents-kong/pkg/subscription" + klib "github.com/kong/go-kong/kong" + + _ "github.com/Axway/agents-kong/pkg/subscription/apikey" // needed for apikey subscription initialization ) -type Client struct { - cfg *config.GatewayConfig - kongClient *kong.Client -} +const kongHash = "kong-hash" +const externalAPIID = "externalAPIID" -func NewClient(gatewayCfg *config.GatewayConfig) (*Client, error) { +func NewClient(agentConfig config.AgentConfig) (*Client, error) { + kongGatewayConfig := agentConfig.KongGatewayCfg clientBase := &http.Client{} - defaultTransport := http.DefaultTransport.(*http.Transport) - clientBase.Transport = defaultTransport + kongClient, err := kutil.NewKongClient(clientBase, kongGatewayConfig) + if err != nil { + return nil, err + } - headers := make(http.Header) - headers.Set("Kong-Admin-Token", gatewayCfg.Token) - client := kong.HTTPClientWithHeaders(clientBase, headers) + apicClient := NewCentralClient(agent.GetCentralClient(), agentConfig.CentralCfg) + + if agentConfig.KongGatewayCfg.SpecDevPortalEnabled { + specmanager.AddSource(devportal.NewSpecificationSource(kongClient)) + } + if len(agentConfig.KongGatewayCfg.SpecHomePath) > 0 { + specmanager.AddSource(localdir.NewSpecificationSource(agentConfig.KongGatewayCfg.SpecHomePath)) + } - kongClient, err := kong.NewClient(&gatewayCfg.AdminEndpoint, &client) + sm, err := initSubscriptionManager(kongClient.Client) if err != nil { return nil, err } - // kongClient.SetDebugMode(true) return &Client{ - cfg: gatewayCfg, - kongClient: kongClient, + centralCfg: agentConfig.CentralCfg, + kongGatewayCfg: kongGatewayConfig, + kongClient: kongClient, + apicClient: apicClient, + subscriptionManager: sm, }, nil } -type ExternalAPI struct { - swaggerSpec []byte - id string - name string - description string - version string - url string - documentation []byte -} - -// DiscoverAPIs - Process the API discovery func (gc *Client) DiscoverAPIs() error { - ctx := context.Background() - gc.GetAllServices(ctx) - // Gateway specific implementation to get the details for discovered API goes here - // Set the service definition - // As sample the implementation reads the swagger for musical-instrument from local directory - swaggerSpec, err := gc.getSpec() + apiServices, err := gc.apicClient.fetchCentralAPIServices(nil) + if err != nil { + log.Infof("failed to get central api services: %s", err) + } + // TODO: initCache should only run once + initCache(apiServices) + + services, err := gc.kongClient.ListServices(context.Background()) if err != nil { - log.Infof("Failed to load sample API specification %s ", err.Error()) + log.Errorf("failed to get services: %s", err) + return err } - externalAPI := ExternalAPI{ - id: "65c79285-f550-4617-bf6e-003e617841f2", - name: "Musical-Instrument-Sample", - description: "Sample for API discovery agent", - version: "1.0.0", - url: "", - documentation: []byte("\"Sample documentation for API discovery agent\""), - swaggerSpec: swaggerSpec, + gc.removeDeletedServices(services) + gc.processKongServicesList(services) + return nil +} + +func (gc *Client) removeDeletedServices(services []*klib.Service) { + specCache := cache.GetCache() + log.Info("checking for deleted kong services") + // TODO: add go funcs + for _, serviceID := range specCache.GetKeys() { + if !doesServiceExists(serviceID, services) { + item, err := specCache.Get(serviceID) + if err != nil { + log.Errorf("failed to get cached service: %s", serviceID) + } + cachedService := item.(CachedService) + err = gc.apicClient.deleteCentralAPIService(cachedService) + if err != nil { + log.Errorf("failed to delete service '%s': %s", cachedService.kongServiceName, err) + continue + } + err = specCache.Delete(serviceID) + if err != nil { + log.Errorf("failed to delete service '%s' from the cache: %s", cachedService.kongServiceName, err) + } + } } +} - serviceBody, err := gc.buildServiceBody(externalAPI) +func (gc *Client) processKongServicesList(services []*klib.Service) { + wg := new(sync.WaitGroup) + + for _, service := range services { + wg.Add(1) + + go func(service *klib.Service, wg *sync.WaitGroup) { + defer wg.Done() + + err := gc.processSingleKongService(context.Background(), service) + if err != nil { + log.Error(err) + } + }(service, wg) + } + + wg.Wait() +} + +func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Service) error { + proxyEndpoint := gc.kongGatewayCfg.ProxyEndpoint + httpPort := gc.kongGatewayCfg.ProxyHttpPort + httpsPort := gc.kongGatewayCfg.ProxyHttpsPort + + routes, err := gc.kongClient.ListRoutesForService(ctx, *service.ID) if err != nil { return err } - err = agent.PublishAPI(serviceBody) + + // delete services that have no routes + if len(routes) == 0 { + log.Warnf("kong service '%s' has no routes. Attempting to delete the service from central", *service.Name) + item, _ := cache.GetCache().Get(*service.ID) + + if svc, ok := item.(CachedService); ok { + err := gc.apicClient.deleteCentralAPIService(svc) + + if err != nil { + log.Errorf("failed to delete service '%' from central: %s", err) + } else { + log.Warnf("deleted Kong service '%s' from central", *service.Name) + } + + cache.GetCache().Delete(*service.ID) + } + return nil + } + + route := routes[0] + + plugins := kutil.Plugins{PluginLister: gc.kongClient.GetKongPlugins()} + ep, err := plugins.GetEffectivePlugins(*route.ID, *service.ID) + if err != nil { + return fmt.Errorf("failed to get plugins for route %s: %w", *route.ID, err) + } + + subscriptionInfo := gc.subscriptionManager.GetSubscriptionInfo(ep) + + endpoints := gc.processKongRoute(proxyEndpoint, route, httpPort, httpsPort) + + kongServiceSpec, err := specmanager.GetSpecification(ctx, service) + if err != nil { + // TODO: If no spec is found, then it was likely deleted, and should be deleted from central + return fmt.Errorf("failed to get spec for %s: %s", *service.Name, err) + } + + oasSpec := Openapi{ + spec: kongServiceSpec.Contents, + } + + serviceBody, err := gc.processKongAPI(*route.ID, service, oasSpec, endpoints, subscriptionInfo) if err != nil { return err } - log.Info("Published API " + serviceBody.APIName + "to AMPLIFY Central") - return err + if serviceBody == nil { + return fmt.Errorf("not processing '%s' since no changes were detected", *service.Name) + } + + err = agent.PublishAPI(*serviceBody) + if err != nil { + return fmt.Errorf("failed to publish api: %s", err) + } + + log.Info("Published API " + serviceBody.APIName + " to AMPLIFY Central") + + return nil } -// buildServiceBody - creates the service definition -func (gc *Client) buildServiceBody(externalAPI ExternalAPI) (apic.ServiceBody, error) { - return apic.NewServiceBodyBuilder(). - SetID(externalAPI.id). - SetTitle(externalAPI.name). - SetURL(externalAPI.url). - SetDescription(externalAPI.description). - SetAPISpec(externalAPI.swaggerSpec). - SetVersion(externalAPI.version). - SetAuthPolicy(apic.Passthrough). - SetDocumentation(externalAPI.documentation). - SetResourceType(apic.Oas2). - Build() +func (gc *Client) processKongRoute(defaultHost string, route *klib.Route, httpPort, httpsPort int) []InstanceEndpoint { + var endpoints []InstanceEndpoint + if route == nil { + return endpoints + } + + hosts := route.Hosts + hosts = append(hosts, &defaultHost) + + for _, host := range hosts { + for _, path := range route.Paths { + for _, protocol := range route.Protocols { + port := httpPort + if *protocol == "https" { + port = httpsPort + } + endpoint := InstanceEndpoint{ + Host: *host, + Port: int32(port), + Protocol: *protocol, + Routing: v1alpha1.ApiServiceInstanceSpecRouting{BasePath: *path}, + } + endpoints = append(endpoints, endpoint) + } + } + } + + return endpoints } -func (gc *Client) getSpec() ([]byte, error) { - return []byte("{}"), nil +func (gc *Client) processKongAPI( + routeID string, + service *klib.Service, + oasSpec Openapi, + endpoints []InstanceEndpoint, + subscriptionInfo subscription.Info, +) (*apic.ServiceBody, error) { + name := gc.centralCfg.GetEnvironmentName() + "." + *service.Name + kongAPI := newKongAPI(routeID, service, oasSpec, endpoints, name, subscriptionInfo) + + serviceBody, err := kongAPI.buildServiceBody() + if err != nil { + return nil, fmt.Errorf("failed to build service body: %v", serviceBody) + } + + serviceBodyHash, _ := util.ComputeHash(serviceBody) + hash := fmt.Sprintf("%v", serviceBodyHash) + serviceBody.ServiceAttributes[kongHash] = hash + + isCached := setCachedService(*service.ID, *service.Name, hash, serviceBody.APIName) + if isCached { + return nil, nil + } + + return &serviceBody, nil } -func (gc *Client) GetService(ctx context.Context, service string) (*kong.Service, error) { - servicesClient := gc.kongClient.Services - return servicesClient.Get(ctx, &service) +func newKongAPI( + routeID string, + service *klib.Service, + oasSpec Openapi, + endpoints []InstanceEndpoint, + nameToPush string, + info subscription.Info, +) KongAPI { + return KongAPI{ + id: routeID, + name: *service.Name, + description: oasSpec.Description(), + version: oasSpec.Version(), + url: *service.Host, + resourceType: oasSpec.ResourceType(), + documentation: []byte("\"Sample documentation for API discovery agent\""), + swaggerSpec: []byte(oasSpec.spec), + endpoints: endpoints, + nameToPush: nameToPush, + subscriptionInfo: info, + } } -func (gc *Client) GetAllServices(ctx context.Context) ([]*kong.Service, error) { - servicesClient := gc.kongClient.Services - return servicesClient.ListAll(ctx) +func (ka *KongAPI) buildServiceBody() (apic.ServiceBody, error) { + serviceAttribute := make(map[string]string) + body := apic.NewServiceBodyBuilder(). + SetAPIName(ka.name). + SetAPISpec(ka.swaggerSpec). + SetDescription(ka.description). + SetDocumentation(ka.documentation). + SetID(ka.id). + SetResourceType(ka.resourceType). + SetServiceAttribute(serviceAttribute). + SetTitle(ka.name). + SetURL(ka.url). + SetVersion(ka.version). + SetServiceEndpoints(ka.endpoints). + SetAuthPolicy(ka.subscriptionInfo.APICPolicyName). + SetSubscriptionName(ka.subscriptionInfo.SchemaName) + + sb, err := body.Build() + + // TODO: add set method for NameToPush + if err == nil { + sb.NameToPush = ka.nameToPush + } + + return sb, err +} + +func doesServiceExists(serviceId string, services []*klib.Service) bool { + for _, srv := range services { + if serviceId == *srv.ID { + return true + } + } + log.Infof("Kong service '%s' no longer exists.", serviceId) + return false +} + +func initSubscriptionManager(kc *klib.Client) (*subscription.Manager, error) { + sm := subscription.New( + logrus.StandardLogger(), + agent.GetCentralClient(), + agent.GetCentralClient(), + kc) + + // register schemas + for _, schema := range sm.Schemas() { + if err := agent.GetCentralClient().RegisterSubscriptionSchema(schema); err != nil { + return nil, fmt.Errorf("failed to register subscription schema %s: %w", schema.GetSubscriptionName(), err) + } + log.Infof("Schema registered: %s", schema.GetSubscriptionName()) + } + + agent.GetCentralClient().GetSubscriptionManager().RegisterValidator(sm.ValidateSubscription) + // register validator and handlers + agent.GetCentralClient().GetSubscriptionManager().RegisterProcessor(apic.SubscriptionApproved, sm.ProcessSubscribe) + + // start polling for subscriptions + agent.GetCentralClient().GetSubscriptionManager().Start() + + return sm, nil } diff --git a/pkg/gateway/definitions.go b/pkg/gateway/definitions.go index 915f1c9..344d3ef 100644 --- a/pkg/gateway/definitions.go +++ b/pkg/gateway/definitions.go @@ -1,28 +1,42 @@ package gateway -// Headers - Type for request/response headers -type Headers map[string]string +import ( + "github.com/Axway/agents-kong/pkg/kong" + "github.com/Axway/agents-kong/pkg/subscription" -// GwTransaction - Type for gateway transaction detail -type GwTransaction struct { - ID string `json:"id"` - SourceHost string `json:"srcHost"` - SourcePort int `json:"srcPort"` - DesHost string `json:"destHost"` - DestPort int `json:"destPort"` - URI string `json:"uri"` - Method string `json:"method"` - StatusCode int `json:"statusCode"` - RequestHeaders Headers `json:"requestHeaders"` - ResponseHeaders Headers `json:"responseHeaders"` - RequestBytes int `json:"requestByte"` - ResponseBytes int `json:"responseByte"` + "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" + corecfg "github.com/Axway/agent-sdk/pkg/config" + + config "github.com/Axway/agents-kong/pkg/config/discovery" +) + +type InstanceEndpoint = v1alpha1.ApiServiceInstanceSpecEndpoint + +type Client struct { + centralCfg corecfg.CentralConfig + kongGatewayCfg *config.KongGatewayConfig + kongClient kong.KongAPIClient + apicClient CentralClient + subscriptionManager *subscription.Manager +} + +type KongAPI struct { + swaggerSpec []byte + id string + name string + description string + version string + url string + documentation []byte + resourceType string + endpoints []InstanceEndpoint + subscriptionInfo subscription.Info + nameToPush string } -// GwTrafficLogEntry - Represents the structure of log entry the agent will receive -type GwTrafficLogEntry struct { - TraceID string `json:"traceId"` - APIName string `json:"apiName"` - InboundTransaction GwTransaction `json:"inbound"` - OutboundTransaction GwTransaction `json:"outbound"` +type CachedService struct { + kongServiceId string + kongServiceName string + hash string + centralName string } diff --git a/pkg/gateway/eventmapper.go b/pkg/gateway/eventmapper.go deleted file mode 100644 index 51d8cff..0000000 --- a/pkg/gateway/eventmapper.go +++ /dev/null @@ -1,123 +0,0 @@ -package gateway - -import ( - "encoding/json" - "net/http" - "strconv" - "time" - - "github.com/Axway/agent-sdk/pkg/agent" - "github.com/Axway/agent-sdk/pkg/transaction" - "github.com/Axway/agent-sdk/pkg/util/log" -) - -// EventMapper - -type EventMapper struct { -} - -func (m *EventMapper) processMapping(gatewayTrafficLogEntry GwTrafficLogEntry) ([]*transaction.LogEvent, error) { - centralCfg := agent.GetCentralConfig() - - eventTime := time.Now().Unix() - txID := gatewayTrafficLogEntry.TraceID - txEventID := gatewayTrafficLogEntry.InboundTransaction.ID - txDetails := gatewayTrafficLogEntry.InboundTransaction - transInboundLogEventLeg, err := m.createTransactionEvent(eventTime, txID, txDetails, txEventID, "", "Inbound") - if err != nil { - return nil, err - } - - txEventID = gatewayTrafficLogEntry.OutboundTransaction.ID - txParentEventID := gatewayTrafficLogEntry.InboundTransaction.ID - txDetails = gatewayTrafficLogEntry.OutboundTransaction - transOutboundLogEventLeg, err := m.createTransactionEvent(eventTime, txID, txDetails, txEventID, txParentEventID, "Outbound") - if err != nil { - return nil, err - } - - transSummaryLogEvent, err := m.createSummaryEvent(eventTime, txID, gatewayTrafficLogEntry, centralCfg.GetTeamID()) - if err != nil { - return nil, err - } - - return []*transaction.LogEvent{ - transSummaryLogEvent, - transInboundLogEventLeg, - transOutboundLogEventLeg, - }, nil -} - -func (m *EventMapper) getTransactionEventStatus(code int) transaction.TxEventStatus { - if code >= 400 { - return transaction.TxEventStatusFail - } - return transaction.TxEventStatusFail -} - -func (m *EventMapper) getTransactionSummaryStatus(statusCode int) transaction.TxSummaryStatus { - transSummaryStatus := transaction.TxSummaryStatusUnknown - if statusCode >= http.StatusOK && statusCode < http.StatusBadRequest { - transSummaryStatus = transaction.TxSummaryStatusSuccess - } else if statusCode >= http.StatusBadRequest && statusCode < http.StatusInternalServerError { - transSummaryStatus = transaction.TxSummaryStatusFailure - } else if statusCode >= http.StatusInternalServerError && statusCode < http.StatusNetworkAuthenticationRequired { - transSummaryStatus = transaction.TxSummaryStatusException - } - return transSummaryStatus -} - -func (m *EventMapper) buildHeaders(headers map[string]string) string { - jsonHeader, err := json.Marshal(headers) - if err != nil { - log.Error(err.Error()) - } - return string(jsonHeader) -} - -func (m *EventMapper) createTransactionEvent(eventTime int64, txID string, txDetails GwTransaction, eventID, parentEventID, direction string) (*transaction.LogEvent, error) { - - httpProtocolDetails, err := transaction.NewHTTPProtocolBuilder(). - SetURI(txDetails.URI). - SetMethod(txDetails.Method). - SetStatus(txDetails.StatusCode, http.StatusText(txDetails.StatusCode)). - SetHost(txDetails.SourceHost). - SetHeaders(m.buildHeaders(txDetails.RequestHeaders), m.buildHeaders(txDetails.ResponseHeaders)). - SetByteLength(txDetails.RequestBytes, txDetails.ResponseBytes). - SetRemoteAddress("", txDetails.DesHost, txDetails.DestPort). - SetLocalAddress(txDetails.SourceHost, txDetails.SourcePort). - Build() - if err != nil { - return nil, err - } - - return transaction.NewTransactionEventBuilder(). - SetTimestamp(eventTime). - SetTransactionID(txID). - SetID(eventID). - SetParentID(parentEventID). - SetSource(txDetails.SourceHost + ":" + strconv.Itoa(txDetails.SourcePort)). - SetDestination(txDetails.DesHost + ":" + strconv.Itoa(txDetails.DestPort)). - SetDirection(direction). - SetStatus(m.getTransactionEventStatus(txDetails.StatusCode)). - SetProtocolDetail(httpProtocolDetails). - Build() -} - -func (m *EventMapper) createSummaryEvent(eventTime int64, txID string, gatewayTrafficLogEntry GwTrafficLogEntry, teamID string) (*transaction.LogEvent, error) { - statusCode := gatewayTrafficLogEntry.InboundTransaction.StatusCode - method := gatewayTrafficLogEntry.InboundTransaction.Method - uri := gatewayTrafficLogEntry.InboundTransaction.URI - host := gatewayTrafficLogEntry.InboundTransaction.SourceHost - - return transaction.NewTransactionSummaryBuilder(). - SetTimestamp(eventTime). - SetTransactionID(txID). - SetStatus(m.getTransactionSummaryStatus(statusCode), strconv.Itoa(statusCode)). - SetTeam(teamID). - SetEntryPoint("http", method, uri, host). - // If the API is published to Central as unified catalog item/API service, se the Proxy details with the API definition - // The Proxy.Name represents the name of the API - // The Proxy.ID should be of format "remoteApiId_". Use transaction.FormatProxyID() to get the formatted value. - SetProxy("unknown", "", 0). - Build() -} diff --git a/pkg/gateway/logreader.go b/pkg/gateway/logreader.go deleted file mode 100644 index 8ac72f9..0000000 --- a/pkg/gateway/logreader.go +++ /dev/null @@ -1,32 +0,0 @@ -package gateway - -import ( - config "github.com/Axway/agents-kong/pkg/config/traceability" - "github.com/hpcloud/tail" -) - -// LogReader - Represents the Gateway client -type LogReader struct { - cfg *config.GatewayConfig - eventChannel chan string -} - -// NewLogReader - Creates a new Gateway Client -func NewLogReader(gatewayCfg *config.GatewayConfig, eventChannel chan string) (*LogReader, error) { - return &LogReader{ - cfg: gatewayCfg, - eventChannel: eventChannel, - }, nil -} - -// Start - Starts reading log file -func (r *LogReader) Start() { - go r.tailFile() -} - -func (r LogReader) tailFile() { - t, _ := tail.TailFile(r.cfg.LogFile, tail.Config{Follow: true}) - for line := range t.Lines { - r.eventChannel <- line.Text - } -} diff --git a/pkg/gateway/openapi.go b/pkg/gateway/openapi.go new file mode 100644 index 0000000..2a1df8f --- /dev/null +++ b/pkg/gateway/openapi.go @@ -0,0 +1,32 @@ +package gateway + +import ( + "github.com/Axway/agent-sdk/pkg/apic" + "github.com/Axway/agent-sdk/pkg/util/log" + "github.com/tidwall/gjson" +) + +type Openapi struct { + spec string +} + +func (oas *Openapi) ResourceType() string { + oas2 := gjson.Get(oas.spec, "swagger").Str + oas3 := gjson.Get(oas.spec, "openapi").Str + if len(oas2) > 0 { + return apic.Oas2 + } + if len(oas3) > 0 { + return apic.Oas3 + } + log.Error("not a valid spec") + return "" +} + +func (oas *Openapi) Description() string { + return gjson.Get(oas.spec, "info.description").Str +} + +func (oas *Openapi) Version() string { + return gjson.Get(oas.spec, "info.version").Str +} diff --git a/pkg/kong/definitions.go b/pkg/kong/definitions.go new file mode 100644 index 0000000..0630101 --- /dev/null +++ b/pkg/kong/definitions.go @@ -0,0 +1,21 @@ +package kong + +import "net/http" + +type DoRequest interface { + Do(req *http.Request) (*http.Response, error) +} + +type DocumentObjects struct { + Data []DocumentObject `json:"data,omitempty"` + Next string `json:"next,omitempty"` +} + +type DocumentObject struct { + CreatedAt int `json:"created_at,omitempty"` + ID string `json:"id,omitempty"` + Path string `json:"path,omitempty"` + Service struct { + ID string `json:"id,omitempty"` + } `json:"service,omitempty"` +} diff --git a/pkg/kong/kongclient.go b/pkg/kong/kongclient.go new file mode 100644 index 0000000..054a17f --- /dev/null +++ b/pkg/kong/kongclient.go @@ -0,0 +1,112 @@ +package kong + +import ( + "context" + "encoding/json" + "fmt" + "github.com/Axway/agents-kong/pkg/kong/specmanager" + "io/ioutil" + "net/http" + + config "github.com/Axway/agents-kong/pkg/config/discovery" + + klib "github.com/kong/go-kong/kong" +) + +type KongAPIClient interface { + ListServices(ctx context.Context) ([]*klib.Service, error) + ListRoutesForService(ctx context.Context, serviceId string) ([]*klib.Route, error) + GetSpecForService(ctx context.Context, serviceId string) (*specmanager.KongServiceSpec, error) + GetKongPlugins() *Plugins +} + +type KongClient struct { + *klib.Client + baseClient DoRequest + kongAdminEndpoint string +} + +func NewKongClient(baseClient *http.Client, kongConfig *config.KongGatewayConfig) (*KongClient, error) { + defaultTransport := http.DefaultTransport.(*http.Transport) + baseClient.Transport = defaultTransport + + headers := make(http.Header) + headers.Set("Kong-Admin-Token", kongConfig.Token) + client := klib.HTTPClientWithHeaders(baseClient, headers) + + baseKongClient, err := klib.NewClient(&kongConfig.AdminEndpoint, &client) + if err != nil { + return nil, err + } + return &KongClient{ + Client: baseKongClient, + baseClient: &client, + kongAdminEndpoint: kongConfig.AdminEndpoint, + }, nil +} + +func (k KongClient) ListServices(ctx context.Context) ([]*klib.Service, error) { + return k.Services.ListAll(ctx) +} + +func (k KongClient) ListRoutesForService(ctx context.Context, serviceId string) ([]*klib.Route, error) { + routes, _, err := k.Routes.ListForService(ctx, &serviceId, nil) + return routes, err +} + +func (k KongClient) GetSpecForService(ctx context.Context, serviceId string) (*specmanager.KongServiceSpec, error) { + endpoint := fmt.Sprintf("%s/services/%s/document_objects", k.kongAdminEndpoint, serviceId) + req, err := http.NewRequestWithContext(ctx, "GET", endpoint, nil) + if err != nil { + return nil, fmt.Errorf("failed to create request: %s", err) + } + res, err := k.baseClient.Do(req) + if err != nil { + return nil, fmt.Errorf("failed to execute request: %s", err) + } + data, err := ioutil.ReadAll(res.Body) + if err != nil { + return nil, fmt.Errorf("failed to read body: %s", err) + } + documents := &DocumentObjects{} + err = json.Unmarshal(data, documents) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal: %s", err) + } + if len(documents.Data) < 1 { + return nil, fmt.Errorf("no documents found") + } + return k.getSpec(ctx, documents.Data[0].Path) +} + +func (k KongClient) getSpec(ctx context.Context, path string) (*specmanager.KongServiceSpec, error) { + endpoint := fmt.Sprintf("%s/default/files/%s", k.kongAdminEndpoint, path) + req, err := http.NewRequestWithContext(ctx, "GET", endpoint, nil) + if err != nil { + return nil, fmt.Errorf("failed to create request: %s", err) + } + + res, err := k.baseClient.Do(req) + if err != nil { + return nil, fmt.Errorf("failed to execute request: %s", err) + } + + data, err := ioutil.ReadAll(res.Body) + if err != nil { + return nil, fmt.Errorf("failed to read body: %s", err) + } + + kongServiceSpec := &specmanager.KongServiceSpec{} + err = json.Unmarshal(data, kongServiceSpec) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal: %s", err) + } + if len(kongServiceSpec.Contents) == 0 { + return nil, fmt.Errorf("spec not found at '%s'", path) + } + return kongServiceSpec, nil +} + +func (k KongClient) GetKongPlugins() *Plugins { + return &Plugins{PluginLister: k.Plugins} +} diff --git a/pkg/kong/plugins.go b/pkg/kong/plugins.go new file mode 100644 index 0000000..faf7248 --- /dev/null +++ b/pkg/kong/plugins.go @@ -0,0 +1,75 @@ +package kong + +import ( + "context" + + klib "github.com/kong/go-kong/kong" +) + +type Plugins struct { + PluginLister +} + +type PluginLister interface { + ListAll(ctx context.Context) ([]*klib.Plugin, error) +} + +// determines the most specific +func mostSpecific(p1, p2 *klib.Plugin) *klib.Plugin { + if p1 == nil { + return p2 + } + + if p2 == nil { + return p1 + } + + if p1.Service != nil && p1.Route != nil { // can't be more specific than this + return p1 + } + if p2.Service != nil && p2.Route != nil { // can't be more specific than this + return p2 + } + + if p1.Route != nil { // route is more specific + return p1 + } + + if p2.Route != nil { + return p2 + } + + if p1.Service != nil { // + return p1 + } + + if p2.Service != nil { // + return p2 + } + + return p2 +} + +// GetEffectivePlugins determines the effective plugin configuration for the route/service combination. +// Returns a map containing effective Plugin configuration grouped by plugin type. +func (p *Plugins) GetEffectivePlugins(routeID, serviceID string) (map[string]*klib.Plugin, error) { + plugins, err := p.ListAll(context.Background()) + if err != nil { + return nil, err + } + + // log.Infof("found %d plugins", len(plugins)) + + pmap := map[string]*klib.Plugin{} + + for _, plugin := range plugins { + if (plugin.Route != nil && (plugin.Route.ID == nil || *plugin.Route.ID != routeID)) || + (plugin.Service != nil && (plugin.Service.ID == nil || *plugin.Service.ID != serviceID)) { + continue + } + + pmap[*plugin.Name] = mostSpecific(pmap[*plugin.Name], plugin) + } + + return pmap, nil +} diff --git a/pkg/kong/plugins_test.go b/pkg/kong/plugins_test.go new file mode 100644 index 0000000..1909028 --- /dev/null +++ b/pkg/kong/plugins_test.go @@ -0,0 +1,122 @@ +package kong_test + +import ( + "context" + "testing" + + "github.com/Axway/agents-kong/pkg/kong" + klib "github.com/kong/go-kong/kong" +) + +type pluginsMock []*klib.Plugin + +func (pm pluginsMock) ListAll(_ context.Context) ([]*klib.Plugin, error) { + return pm, nil +} + +func p(id, name string) *klib.Plugin { + return &klib.Plugin{ + ID: &id, + Name: &name, + } +} + +func pwr(id, name, routeID string) *klib.Plugin { + return &klib.Plugin{ + ID: &id, + Name: &name, + Route: &klib.Route{ + ID: &routeID, + }, + } +} + +func pws(id, name, serviceID string) *klib.Plugin { + return &klib.Plugin{ + ID: &id, + Name: &name, + Service: &klib.Service{ + ID: &serviceID, + }, + } +} + +func pwrs(id, name, routeID, serviceID string) *klib.Plugin { + return &klib.Plugin{ + ID: &id, + Name: &name, + Route: &klib.Route{ + ID: &routeID, + }, + Service: &klib.Service{ + ID: &serviceID, + }, + } +} + +func TestGetEffectivePlugins(t *testing.T) { + var routeID = "routeID" + var serviceID = "serviceID" + testCases := []struct { + name string + plugins []*klib.Plugin + expectedIds map[string]interface{} + }{{ + "one plugin with routeID", + []*klib.Plugin{p("1", "api-key")}, + map[string]interface{}{"1": nil}, + }, { + "plugin on route takes precedence", + []*klib.Plugin{ + p("1", "api-key"), + pwr("2", "api-key", routeID), + pws("3", "api-key", serviceID), + }, + map[string]interface{}{"2": nil}, + }, { + "plugin on service takes precedence", + []*klib.Plugin{ + p("1", "api-key"), + pws("3", "api-key", serviceID), + }, + map[string]interface{}{"3": nil}, + }, { + "multiple plugin types still correct", + []*klib.Plugin{ + p("1", "api-key"), + pws("2", "api-key", serviceID), + pwr("3", "acl", routeID), + pws("4", "acl", serviceID), + pwrs("5", "acl", "otherRoute", serviceID), + }, + map[string]interface{}{"2": nil, "3": nil}, + }} + + for i := range testCases { + tc := testCases[i] + t.Run(tc.name, func(t *testing.T) { + + plugins := kong.Plugins{pluginsMock(tc.plugins)} + + res, err := plugins.GetEffectivePlugins(routeID, serviceID) + if err != nil { + t.Fatalf("Failed due: %s", err) + } + + for _, plugin := range res { + if _, ok := tc.expectedIds[*plugin.ID]; !ok { + t.Error("unexpected plugin with id:", *plugin.ID) + continue + } + + delete(tc.expectedIds, *plugin.ID) + } + + if len(tc.expectedIds) != 0 { + for k := range tc.expectedIds { + t.Error("missing plugin with id:", k) + } + } + }) + } +} diff --git a/pkg/kong/specmanager/devportal/devportal.go b/pkg/kong/specmanager/devportal/devportal.go new file mode 100644 index 0000000..ca40cf0 --- /dev/null +++ b/pkg/kong/specmanager/devportal/devportal.go @@ -0,0 +1,28 @@ +package devportal + +import ( + "context" + kutil "github.com/Axway/agents-kong/pkg/kong" + "github.com/Axway/agents-kong/pkg/kong/specmanager" + klib "github.com/kong/go-kong/kong" +) + +type sourceConfig struct { + name string + kongClient kutil.KongAPIClient +} + +func NewSpecificationSource(kongClient kutil.KongAPIClient) specmanager.SpecificationSource { + return sourceConfig{ + name: "dev-portal", + kongClient: kongClient, + } +} + +func (sc sourceConfig) Name() *string { + return &sc.name +} + +func (sc sourceConfig) GetSpecForService(ctx context.Context, service *klib.Service) (*specmanager.KongServiceSpec, error) { + return sc.kongClient.GetSpecForService(ctx, *service.ID) +} diff --git a/pkg/kong/specmanager/localdir/localdir.go b/pkg/kong/specmanager/localdir/localdir.go new file mode 100644 index 0000000..8eec522 --- /dev/null +++ b/pkg/kong/specmanager/localdir/localdir.go @@ -0,0 +1,72 @@ +package localdir + +import ( + "context" + "fmt" + "github.com/Axway/agent-sdk/pkg/util/log" + "github.com/Axway/agents-kong/pkg/kong/specmanager" + klib "github.com/kong/go-kong/kong" + "io/ioutil" + "os" + "path" + "strings" +) + +const tagPrefix = "spec_local_" + +type sourceConfig struct { + name string + rootPath string +} + +func NewSpecificationSource(rootPath string) specmanager.SpecificationSource { + return sourceConfig{ + name: "local", + rootPath: rootPath, + } +} + +func (sc sourceConfig) Name() *string { + return &sc.name +} + +func (sc sourceConfig) GetSpecForService(ctx context.Context, service *klib.Service) (*specmanager.KongServiceSpec, error) { + specTag := "" + for _, tag := range service.Tags { + if strings.HasPrefix(*tag, tagPrefix) { + specTag = *tag + } + } + + if len(specTag) > 0 { + name := specTag[len(tagPrefix):] + + return sc.loadSpecFile(name) + } + log.Info("no specification tag found for service %s (%s)", *service.Name, *service.ID) + return nil, nil +} + +func (sc sourceConfig) loadSpecFile(name string) (*specmanager.KongServiceSpec, error) { + specFilePath := path.Join(sc.rootPath, name) + + if _, err := os.Stat(specFilePath); os.IsNotExist(err) { + log.Warnf("specification file not found %s", specFilePath) + return nil, nil + } + + data, err := ioutil.ReadFile(specFilePath) + if err != nil { + return nil, fmt.Errorf("error on reading spec file %s: %s", specFilePath, err) + } + + kongServiceSpec := &specmanager.KongServiceSpec{ + Contents: string(data), + CreatedAt: 0, + ID: "", + Path: specFilePath, + Checksum: "", + } + + return kongServiceSpec, nil +} diff --git a/pkg/kong/specmanager/specmanager.go b/pkg/kong/specmanager/specmanager.go new file mode 100644 index 0000000..c4aeff0 --- /dev/null +++ b/pkg/kong/specmanager/specmanager.go @@ -0,0 +1,42 @@ +package specmanager + +import ( + "context" + "fmt" + "github.com/Axway/agent-sdk/pkg/util/log" + "github.com/kong/go-kong/kong" +) + +type KongServiceSpec struct { + Contents string `json:"contents"` + CreatedAt int `json:"created_at"` + ID string `json:"id"` + Path string `json:"path"` + Checksum string `json:"checksum"` +} + +type SpecificationSource interface { + Name() *string + GetSpecForService(ctx context.Context, service *kong.Service) (*KongServiceSpec, error) +} + +var specificationManager struct { + sources []SpecificationSource +} + +func AddSource(source SpecificationSource) { + specificationManager.sources = append(specificationManager.sources, source) + log.Infof("specification source added: %s", *source.Name()) +} + +func GetSpecification(ctx context.Context, service *kong.Service) (*KongServiceSpec, error) { + for _, source := range specificationManager.sources { + spec, err := source.GetSpecForService(ctx, service) + if err == nil { + if spec != nil { + return spec, nil + } + } + } + return nil, fmt.Errorf("no specification found for service %s (%s)", *service.Name, *service.ID) +} diff --git a/pkg/processor/definitions.go b/pkg/processor/definitions.go new file mode 100644 index 0000000..122add2 --- /dev/null +++ b/pkg/processor/definitions.go @@ -0,0 +1,85 @@ +package processor + +// KongTrafficLogEntry - Represents the structure of log entry the agent will receive from Kong's HTTP Log Plugin +type KongTrafficLogEntry struct { + ClientIP string `json:"client_ip"` + StartedAt int64 `json:"started_at"` + UpstreamURI string `json:"upstream_uri"` + Latencies *Latencies `json:"latencies"` + Request *Request `json:"request"` + Response *Response `json:"response"` + Route *Route `json:"route"` + Service *Service `json:"service"` + Tries []*Tries `json:"tries"` +} + +type Latencies struct { + Request int `json:"request"` + Kong int `json:"kong"` + Proxy int `json:"proxy"` +} + +type Request struct { + QueryString map[string]string `json:"querystring"` + Size int `json:"size"` + URI string `json:"uri"` + URL string `json:"url"` + Headers map[string]string `json:"headers"` + Method string `json:"method"` + TLS *TLS `json:"tls"` +} + +type Response struct { + Headers map[string]string `json:"headers"` + Status int `json:"status"` + Size int `json:"size"` +} + +type Route struct { + ID string `json:"id"` + UpdatedAt int `json:"updated_at"` + Protocols []string `json:"protocols"` + StripPath bool `json:"strip_path"` + CreatedAt int `json:"created_at"` + WsID string `json:"ws_id"` + Service map[string]string `json:"service"` + Name string `json:"name"` + Hosts []string `json:"hosts"` + PreserveHost bool `json:"preserve_host"` + RegexPriority int `json:"regex_priority"` + Paths []string `json:"paths"` + ResponseBuffering bool `json:"response_buffering"` + HttpsRedirectStatusCode int `json:"https_redirect_status_code"` + PathHandling string `json:"path_handling"` + RequestBuffering bool `json:"request_buffering"` +} + +type Service struct { + Host string `json:"host"` + CreatedAt int `json:"created_at"` + ConnectTimeout int `json:"connect_timeout"` + ID string `json:"id"` + Protocol string `json:"protocol"` + Name string `json:"name"` + ReadTimeout int `json:"read_timeout"` + Port int `json:"port"` + Path string `json:"path"` + UpdatedAt int `json:"updated_at"` + WriteTimeout int `json:"write_timeout"` + Retries int `json:"retries"` + WsID string `json:"ws_id"` +} + +type Tries struct { + BalancerLatency int `json:"balancer_latency"` + Port int `json:"port"` + BalancerStart int64 `json:"balancer_start"` + IP string `json:"ip"` +} + +type TLS struct { + Version string `json:"version"` + Cipher string `json:"cipher"` + SupportedClientCiphers string `json:"supported_client_ciphers"` + ClientVerify string `json:"client_verify"` +} diff --git a/pkg/processor/eventmapper.go b/pkg/processor/eventmapper.go new file mode 100644 index 0000000..09b3d2f --- /dev/null +++ b/pkg/processor/eventmapper.go @@ -0,0 +1,162 @@ +package processor + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + "strconv" + "strings" + + "github.com/Axway/agent-sdk/pkg/agent" + "github.com/Axway/agent-sdk/pkg/transaction" + "github.com/Axway/agent-sdk/pkg/util/log" +) + +// EventMapper - +type EventMapper struct { +} + +const requestID = "kong-request-id" +const host = "host" +const userAgent = "user-agent" +const hash = "#" + +func (m *EventMapper) processMapping(kongTrafficLogEntry KongTrafficLogEntry) ([]*transaction.LogEvent, error) { + centralCfg := agent.GetCentralConfig() + transactionLegEvent, err := m.createTransactionEvent(kongTrafficLogEntry) + if err != nil { + log.Errorf("Error while building transaction leg event: %s", err) + return nil, err + } + + jTransactionLegEvent, err := json.Marshal(transactionLegEvent) + if err != nil { + log.Errorf("Failed to serialize transaction leg event as json: %s", err) + } + + log.Debug("Generated Transaction leg event: ", string(jTransactionLegEvent)) + + transSummaryLogEvent, err := m.createSummaryEvent(kongTrafficLogEntry, centralCfg.GetTeamID()) + if err != nil { + log.Errorf("Error while building transaction summary event: %s", err) + return nil, err + } + + jTransactionSummary, err := json.Marshal(transSummaryLogEvent) + if err != nil { + log.Errorf("Failed to serialize transaction summary as json: %s", err) + } + + log.Debug("Generated Transaction summary event: ", string(jTransactionSummary)) + + return []*transaction.LogEvent{ + transSummaryLogEvent, + transactionLegEvent, + }, nil +} + +func (m *EventMapper) getTransactionEventStatus(code int) transaction.TxEventStatus { + if code >= 400 { + return transaction.TxEventStatusFail + } + return transaction.TxEventStatusPass +} + +func (m *EventMapper) getTransactionSummaryStatus(statusCode int) transaction.TxSummaryStatus { + transSummaryStatus := transaction.TxSummaryStatusUnknown + if statusCode >= http.StatusOK && statusCode < http.StatusBadRequest { + transSummaryStatus = transaction.TxSummaryStatusSuccess + } else if statusCode >= http.StatusBadRequest && statusCode < http.StatusInternalServerError { + transSummaryStatus = transaction.TxSummaryStatusFailure + } else if statusCode >= http.StatusInternalServerError && statusCode < http.StatusNetworkAuthenticationRequired { + transSummaryStatus = transaction.TxSummaryStatusException + } + return transSummaryStatus +} + +func (m *EventMapper) buildHeaders(headers map[string]string) string { + jsonHeader, err := json.Marshal(headers) + if err != nil { + log.Error(err.Error()) + } + return string(jsonHeader) +} + +func (m *EventMapper) buildSSLInfoIfAvailable(ktle KongTrafficLogEntry) (string, string, string) { + if ktle.Request.TLS != nil { + return ktle.Request.TLS.Version, + ktle.Request.URL, + ktle.Request.URL // Using SSL server name as SSL subject name for now + } + return "", "", "" +} + +func (m *EventMapper) processQueryArgs(args map[string]string) string { + b := new(bytes.Buffer) + for key, value := range args { + fmt.Fprintf(b, "%s=\"%s\",", key, value) + } + return b.String() +} + +func (m *EventMapper) trimRequestId(reqId string) string { + if strings.Contains(reqId, hash) { + return strings.Split(reqId, hash)[0] + } + return reqId +} + +func (m *EventMapper) createTransactionEvent(ktle KongTrafficLogEntry) (*transaction.LogEvent, error) { + + httpProtocolDetails, err := transaction.NewHTTPProtocolBuilder(). + SetURI(ktle.Request.URI). + SetMethod(ktle.Request.Method). + SetArgs(m.processQueryArgs(ktle.Request.QueryString)). + SetStatus(ktle.Response.Status, http.StatusText(ktle.Response.Status)). + SetHost(ktle.Request.Headers[host]). + SetHeaders(m.buildHeaders(ktle.Request.Headers), m.buildHeaders(ktle.Response.Headers)). + SetByteLength(ktle.Request.Size, ktle.Response.Size). + SetRemoteAddress("", "", ktle.Tries[0].Port). // No way to find remote address for now + SetLocalAddress(ktle.ClientIP, 0). // Could not determine local port for now + SetSSLProperties(m.buildSSLInfoIfAvailable(ktle)). + SetUserAgent(ktle.Request.Headers[userAgent]). + Build() + + if err != nil { + log.Errorf("Error while filling protocol details for transaction event: %s", err) + return nil, err + } + + return transaction.NewTransactionEventBuilder(). + SetTimestamp(ktle.StartedAt). + SetTransactionID(m.trimRequestId(ktle.Request.Headers[requestID])). + SetID("leg0"). + SetParentID(""). + SetSource("client_ip"). + SetDestination("backend_api"). + SetDuration(ktle.Latencies.Request). + SetDirection("outbound"). + SetStatus(m.getTransactionEventStatus(ktle.Response.Status)). + SetProtocolDetail(httpProtocolDetails). + Build() +} + +func (m *EventMapper) createSummaryEvent(ktle KongTrafficLogEntry, teamID string) (*transaction.LogEvent, error) { + + return transaction.NewTransactionSummaryBuilder(). + SetTimestamp(ktle.StartedAt). + SetTransactionID(m.trimRequestId(ktle.Request.Headers[requestID])). + SetStatus(m.getTransactionSummaryStatus(ktle.Response.Status), + strconv.Itoa(ktle.Response.Status)). + SetTeam(teamID). + SetEntryPoint(ktle.Service.Protocol, + ktle.Request.Method, + ktle.Request.URI, + ktle.Request.URL). + SetDuration(ktle.Latencies.Request). + SetProxy(transaction.FormatProxyID(ktle.Service.ID), + ktle.Service.Name, + 1). + Build() +} diff --git a/pkg/gateway/eventprocessor.go b/pkg/processor/eventprocessor.go similarity index 61% rename from pkg/gateway/eventprocessor.go rename to pkg/processor/eventprocessor.go index e5254bb..bad523c 100644 --- a/pkg/gateway/eventprocessor.go +++ b/pkg/processor/eventprocessor.go @@ -1,4 +1,4 @@ -package gateway +package processor import ( "encoding/json" @@ -6,10 +6,7 @@ import ( "github.com/Axway/agent-sdk/pkg/transaction" "github.com/Axway/agent-sdk/pkg/util/log" - config "github.com/Axway/agents-kong/pkg/config/traceability" - "github.com/elastic/beats/v7/libbeat/beat" - "github.com/elastic/beats/v7/libbeat/publisher" ) // EventProcessor - represents the processor for received event to generate event(s) for AMPLIFY Central @@ -22,59 +19,35 @@ import ( // log entry and performs the mapping to structure expected for AMPLIFY Central Observer. The method returns the converted Events to // transport publisher which then produces the events over the transport. type EventProcessor struct { - cfg *config.GatewayConfig eventGenerator transaction.EventGenerator eventMapper *EventMapper } // NewEventProcessor - return a new EventProcessor -func NewEventProcessor(gateway *config.GatewayConfig) *EventProcessor { +func NewEventProcessor() *EventProcessor { ep := &EventProcessor{ - cfg: gateway, eventGenerator: transaction.NewEventGenerator(), eventMapper: &EventMapper{}, } return ep } -// Process - callback set as output event processor that gets invoked by transport publisher to process the received events -func (p *EventProcessor) Process(events []publisher.Event) []publisher.Event { - newEvents := make([]publisher.Event, 0) - for _, event := range events { - // Get the message from the log file - eventMsgFieldVal, err := event.Content.Fields.GetValue("message") - if err != nil { - log.Error(err.Error()) - return newEvents - } - - eventMsg, ok := eventMsgFieldVal.(string) - if ok { - // Unmarshal the message into the struct representing traffic log entry in gateway logs - beatEvents := p.ProcessRaw([]byte(eventMsg)) - if beatEvents != nil { - for _, beatEvent := range beatEvents { - publisherEvent := publisher.Event{ - Content: beatEvent, - } - newEvents = append(newEvents, publisherEvent) - } - } - } - } - return newEvents -} - // ProcessRaw - process the received log entry and returns the event to be published to AMPLIFY ingestion service func (p *EventProcessor) ProcessRaw(rawEventData []byte) []beat.Event { - var gatewayTrafficLogEntry GwTrafficLogEntry - err := json.Unmarshal(rawEventData, &gatewayTrafficLogEntry) + var kongTrafficLogEntry KongTrafficLogEntry + err := json.Unmarshal(rawEventData, &kongTrafficLogEntry) if err != nil { log.Error(err.Error()) return nil } + + // Only process those request logs that contain Kong Service details + if kongTrafficLogEntry.Service == nil { + return nil + } + // Map the log entry to log event structure expected by AMPLIFY Central Observer - logEvents, err := p.eventMapper.processMapping(gatewayTrafficLogEntry) + logEvents, err := p.eventMapper.processMapping(kongTrafficLogEntry) if err != nil { log.Error(err.Error()) return nil diff --git a/pkg/server/traceability.go b/pkg/server/traceability.go deleted file mode 100644 index 1af2828..0000000 --- a/pkg/server/traceability.go +++ /dev/null @@ -1,43 +0,0 @@ -package server - -import ( - "fmt" - "io/ioutil" - "net/http" - - log "github.com/Axway/agent-sdk/pkg/util/log" -) - -func NewTraceServer() { - http.HandleFunc("/logs", logHandler) - log.Info("Starting Kong Traceability Agent on port 8080") - err := http.ListenAndServe(":8080", nil) - if err != nil { - panic(err) - } -} - -func logHandler(w http.ResponseWriter, req *http.Request) { - if req.Method != http.MethodPost { - w.WriteHeader(405) - return - } - - // authenticate the request - - // Is it only json? - if req.Header.Get("Content-Type") != "application/json" { - w.WriteHeader(400) - return - } - - body, err := ioutil.ReadAll(req.Body) - if err != nil { - w.WriteHeader(500) - return - } - log.Info(string(body)) - - w.WriteHeader(200) - fmt.Fprint(w, "Kong Traceability Agent") -} diff --git a/pkg/server/traceability_test.go b/pkg/server/traceability_test.go deleted file mode 100644 index 9a0799b..0000000 --- a/pkg/server/traceability_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package server - -import "testing" - -func Test_NewServer(t *testing.T) { - NewTraceServer() -} diff --git a/pkg/subscription/apikey.go b/pkg/subscription/apikey.go new file mode 100644 index 0000000..986cfbf --- /dev/null +++ b/pkg/subscription/apikey.go @@ -0,0 +1,12 @@ +package subscription + +import ( + "github.com/kong/go-kong/kong" +) + +type apiKey struct{} + +const name = "kong-apikey" + +func (*apiKey) AppliesTo(*kong.Route) { +} diff --git a/pkg/subscription/apikey/apikey.go b/pkg/subscription/apikey/apikey.go new file mode 100644 index 0000000..f9e7e48 --- /dev/null +++ b/pkg/subscription/apikey/apikey.go @@ -0,0 +1,206 @@ +package apikey + +import ( + "context" + "fmt" + "strings" + + "github.com/Axway/agent-sdk/pkg/apic" + kutil "github.com/Axway/agents-kong/pkg/kong" + "github.com/Axway/agents-kong/pkg/subscription" + "github.com/kong/go-kong/kong" + "github.com/sirupsen/logrus" +) + +type apiKey struct { + kc *kong.Client +} + +const Name = "kong-apikey" + +const ( + keyPluginName = "key-auth" + propertyName = "api-key" +) + +func init() { + subscription.Register(func(kc *kong.Client) subscription.Handler { + return &apiKey{kc} + }) +} + +func (*apiKey) Name() string { + return Name +} + +func (*apiKey) APICPolicy() string { + return apic.Apikey +} + +// Schema returns the schema +func (*apiKey) Schema() apic.SubscriptionSchema { + schema := apic.NewSubscriptionSchema(Name) + + schema.AddProperty(propertyName, + "string", + "The api key. Leave empty for autogeneration", + "", + false, + nil) + + return schema +} + +// IsApplicable if this subscription method +// is applicable for a route with the given plugins. +func (*apiKey) IsApplicable(plugins map[string]*kong.Plugin) bool { + _, ok := plugins[keyPluginName] + return ok +} + +func (ak *apiKey) Subscribe(log logrus.FieldLogger, subs apic.Subscription) { + key, err := ak.doSubscribe(log, subs) + + if err != nil { + log.WithError(err).Error("Failed to subscribe") + subs.UpdateState(apic.SubscriptionFailedToSubscribe, err.Error()) + return + } + + subs.UpdateStateWithProperties(apic.SubscriptionActive, "", map[string]interface{}{propertyName: key}) +} + +func (ak *apiKey) doSubscribe(log logrus.FieldLogger, subs apic.Subscription) (string, error) { + key := subs.GetPropertyValue(propertyName) + + agentTag := "amplify-agent" + ctx := context.Background() + routeID := subs.GetRemoteAPIID() + subscriptionID := subs.GetID() + subscriptionName := subs.GetName() + "_" + subscriptionID + apicID := subs.GetApicID() + + route, err := ak.kc.Routes.Get(ctx, &routeID) + if err != nil { + return "", fmt.Errorf("failed to get route: %w", err) + } + consumerTags := []*string{&apicID, &agentTag} + + plugins := kutil.Plugins{PluginLister: ak.kc.Plugins} + ep, err := plugins.GetEffectivePlugins(*route.ID, *route.Service.ID) + if err != nil { + return "", fmt.Errorf("failed to list route plugins: %w", err) + } + + consumerRes, update, err := ak.createOrUpdateConsumer(subscriptionName, subscriptionID, consumerTags) + if err != nil { + return "", err + } + + if update { + ak.deleteAllKeys(*consumerRes.ID, subscriptionID) + } + + keyAuth := &kong.KeyAuth{ + Tags: consumerTags, + } + // generate key if not provided + if key != "" { + keyAuth.Key = &key + } + + keyAuthRes, err := ak.kc.KeyAuths.Create(ctx, consumerRes.ID, keyAuth) + if err != nil { + return "", fmt.Errorf("failed to create API Key: %w", err) + } + + acl, ok := ep["acl"] + if !ok { + log.Warn("ACL Plugin is not configured on route / service") + return "", nil + } + + // add group + if groups, ok := acl.Config["allow"].([]interface{}); ok { + group := findACLGroup(groups) + + if group == "" { + return "", fmt.Errorf("failed to find suitable acl group") + } + + _, err = ak.kc.ACLs.Create(ctx, consumerRes.ID, &kong.ACLGroup{Group: &group, Tags: consumerTags}) + if err != nil { + return "", fmt.Errorf("failed to add acl group on consumer: %w", err) + } + } else { + log.Warn("No restrictions on API anybody can call it") + } + + return *keyAuthRes.Key, nil +} + +func (ak *apiKey) createOrUpdateConsumer(name string, customID string, tags []*string) (*kong.Consumer, bool, error) { + ctx := context.TODO() + + consumerRes, err := ak.kc.Consumers.Get(ctx, &name) + if err == nil { + return consumerRes, false, nil + } + + consumerRes, err = ak.kc.Consumers.Create(ctx, &kong.Consumer{ + CustomID: &customID, + Username: &name, + Tags: tags, + }) + if err != nil { + return nil, false, fmt.Errorf("failed to create consumer: %w", err) + } + + return consumerRes, true, nil +} + +func (ak *apiKey) Unsubscribe(log logrus.FieldLogger, subs apic.Subscription) { + log.Info("Delete apikey subscription") + subscriptionID := subs.GetID() + routeID := subs.GetRemoteAPIID() + subscriptionName := subs.GetName() + "_" + subscriptionID + ctx := context.Background() + + err := ak.kc.Consumers.Delete(ctx, &subscriptionName) + if err != nil { + log.WithError(err).Error("Failed to delete Consumer") + subs.UpdateState(apic.SubscriptionFailedToSubscribe, fmt.Sprintf("Failed to create API Key %s: %s", routeID, err)) + return + } + //subs.UpdateState(apic.SubscriptionUnsubscribed, "Toodles") + err = subs.UpdateState(apic.SubscriptionUnsubscribed, "Toodles") + if err != nil { + log.WithError(err).Error("failed to update subscription state") + } +} + +func findACLGroup(groups []interface{}) string { + for _, group := range groups { + if groupStr, ok := group.(string); ok && strings.HasPrefix(groupStr, "amplify.") { + return groupStr + } + } + return "" +} + +func (ak *apiKey) deleteAllKeys(consumerID, subscriptionID string) error { + ctx := context.Background() + keys, _, err := ak.kc.KeyAuths.ListForConsumer(ctx, &consumerID, &kong.ListOpt{Tags: []*string{&subscriptionID}}) + if err != nil { + return fmt.Errorf("failed to list all consumers: %w", err) + } + + for _, k := range keys { + err := ak.kc.KeyAuths.Delete(ctx, &consumerID, k.ID) + if err != nil { + return fmt.Errorf("failed to delete consumer key: ") + } + } + + return nil +} diff --git a/pkg/subscription/package.go b/pkg/subscription/package.go new file mode 100644 index 0000000..5116318 --- /dev/null +++ b/pkg/subscription/package.go @@ -0,0 +1,3 @@ +package subscription + + diff --git a/pkg/subscription/subscription_test.go b/pkg/subscription/subscription_test.go new file mode 100644 index 0000000..9cae2ab --- /dev/null +++ b/pkg/subscription/subscription_test.go @@ -0,0 +1,427 @@ +package subscription_test + +import ( + "context" + "net/http" + "testing" + "time" + + "github.com/kong/go-kong/kong" + + "github.com/Axway/agent-sdk/pkg/agent" + "github.com/Axway/agent-sdk/pkg/apic" + "github.com/Axway/agent-sdk/pkg/config" + kutil "github.com/Axway/agents-kong/pkg/kong" + "github.com/Axway/agents-kong/pkg/subscription" + "github.com/sirupsen/logrus" + + _ "github.com/Axway/agents-kong/pkg/subscription/apikey" +) + +var swagger = ` +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore", + "description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "Swagger API Team" + }, + "license": { + "name": "MIT" + } + }, + "host": "petstore.swagger.io", + "basePath": "/api", + "schemes": [ + "http" + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/pets": { + "get": { + "description": "Returns all pets from the system that the user has access to", + "operationId": "findPets", + "produces": [ + "application/json", + "application/xml", + "text/xml", + "text/html" + ], + "parameters": [ + { + "name": "tags", + "in": "query", + "description": "tags to filter by", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv" + }, + { + "name": "limit", + "in": "query", + "description": "maximum number of results to return", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "responses": { + "200": { + "description": "pet response", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Pet" + } + } + }, + "default": { + "description": "unexpected error", + "schema": { + "$ref": "#/definitions/ErrorModel" + } + } + } + }, + "post": { + "description": "Creates a new pet in the store. Duplicates are allowed", + "operationId": "addPet", + "produces": [ + "application/json" + ], + "parameters": [ + { + "name": "pet", + "in": "body", + "description": "Pet to add to the store", + "required": true, + "schema": { + "$ref": "#/definitions/NewPet" + } + } + ], + "responses": { + "200": { + "description": "pet response", + "schema": { + "$ref": "#/definitions/Pet" + } + }, + "default": { + "description": "unexpected error", + "schema": { + "$ref": "#/definitions/ErrorModel" + } + } + } + } + }, + "/pets/{id}": { + "get": { + "description": "Returns a user based on a single ID, if the user does not have access to the pet", + "operationId": "findPetById", + "produces": [ + "application/json", + "application/xml", + "text/xml", + "text/html" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "description": "ID of pet to fetch", + "required": true, + "type": "integer", + "format": "int64" + } + ], + "responses": { + "200": { + "description": "pet response", + "schema": { + "$ref": "#/definitions/Pet" + } + }, + "default": { + "description": "unexpected error", + "schema": { + "$ref": "#/definitions/ErrorModel" + } + } + } + }, + "delete": { + "description": "deletes a single pet based on the ID supplied", + "operationId": "deletePet", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "ID of pet to delete", + "required": true, + "type": "integer", + "format": "int64" + } + ], + "responses": { + "204": { + "description": "pet deleted" + }, + "default": { + "description": "unexpected error", + "schema": { + "$ref": "#/definitions/ErrorModel" + } + } + } + } + } + }, + "definitions": { + "Pet": { + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/NewPet" + }, + { + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + } + } + } + ] + }, + "NewPet": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "ErrorModel": { + "type": "object", + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } +} +` + +func stringP(in string) *string { + return &in +} + +func TestSubscription(t *testing.T) { + + // + // initialize central client + // set your client id, privateKey, publicKey below + // + err := agent.Initialize(&config.CentralConfiguration{ + AgentType: config.DiscoveryAgent, + Mode: config.PublishToEnvironmentAndCatalog, + TenantID: "251204211014979", + TeamName: "Default Team", + APICDeployment: "prod", + Environment: "vibu", + URL: "https://apicentral.axway.com", + PlatformURL: "https://platform.axway.com", + APIServerVersion: "v1alpha1", + TagsToPublish: "mytag", + AppendDataPlaneToTitle: true, + Auth: &config.AuthConfiguration{ + URL: "https://login.axway.com/auth", + Realm: "Broker", + ClientID: "DOSA_0acaa95063a64ff1ba4d76f2a35287b8", // change + PrivateKey: "/home/vibu/.xenutil/privateKey", // change + PublicKey: "/home/vibu/.xenutil/publicKey", // change + PrivateKeyData: "", + PublicKeyData: "", + KeyPwd: "", + Timeout: 0, + }, + PollInterval: 10, + ProxyURL: "", + SubscriptionConfiguration: config.NewSubscriptionConfig(), + }) + if err != nil { + t.Fatalf("Failed due: %s", err) + } + + // + // initialize kong client + // set your kong url below + // + + kURL := "http://localhost:8001" // change + + k, err := kong.NewClient(&kURL, &http.Client{}) + if err != nil { + t.Fatalf("Failed due: %s", err) + } + + // + // create test kong resources + // + name := stringP("petstore") + // create the route and service + svc, err := k.Services.Create(context.TODO(), &kong.Service{ + Name: name, + Host: stringP("petstore.swagger.io"), + Path: stringP("/v2"), + Protocol: stringP("http"), + }) + if err != nil { + if e, ok := err.(*kong.APIError); !ok || (ok && e.Code() != 409) { + t.Fatalf("Failed due: %s", err) + } + svc, err = k.Services.Get(context.TODO(), name) + if err != nil { + t.Fatalf("Failed due: %s", err) + } + } + route, err := k.Routes.CreateInService(context.TODO(), svc.ID, &kong.Route{ + Name: name, + Hosts: []*string{stringP("localhost")}, + Paths: []*string{stringP("/" + *name)}, + }) + if err != nil { + if e, ok := err.(*kong.APIError); !ok || (ok && e.Code() != 409) { + t.Fatalf("Failed due: %s", err) + } + route, err = k.Routes.Get(context.TODO(), name) + if err != nil { + t.Fatalf("Failed due: %s", err) + } + } + _, err = k.Plugins.Create(context.TODO(), &kong.Plugin{ + Name: stringP("key-auth"), + Route: route, + }) + if err != nil { + if e, ok := err.(*kong.APIError); !ok || (ok && e.Code() != 409) { + t.Fatalf("Failed due: %s", err) + } + } + _, err = k.Plugins.Create(context.TODO(), &kong.Plugin{ + Name: stringP("acl"), + Route: route, + Config: kong.Configuration{ + "allow": []interface{}{"amplify.testsvc"}, + }, + }) + if err != nil { + if e, ok := err.(*kong.APIError); !ok || (ok && e.Code() != 409) { + t.Fatalf("Failed due: %s", err) + } + } + + // + // this should happen as the agent is starting up + // + + sm := subscription.New(logrus.StandardLogger(), + agent.GetCentralClient(), + agent.GetCentralClient(), + k) + + // register schemas + for _, schema := range sm.Schemas() { + err := agent.GetCentralClient().RegisterSubscriptionSchema(schema) + if err != nil { + t.Fatalf("Failed due: %s", err) + } + } + + // register validator and handlers + agent.GetCentralClient().GetSubscriptionManager().RegisterValidator(sm.ValidateSubscription) + // register validator and handlers + agent.GetCentralClient().GetSubscriptionManager().RegisterProcessor(apic.SubscriptionApproved, sm.ProcessSubscribe) + agent.GetCentralClient().GetSubscriptionManager().RegisterProcessor(apic.SubscriptionUnsubscribeInitiated, sm.ProcessUnsubscribe) + + // start polling for subscriptions + agent.GetCentralClient().GetSubscriptionManager().Start() + + pl := kutil.Plugins{PluginLister: k.Plugins} + ep, err := pl.GetEffectivePlugins(*route.ID, *svc.ID) + if err != nil { + t.Fatalf("Failed due: %s", err) + } + + info := sm.GetSubscriptionInfo(ep) + // + // this should happen for each service + // + + sb := apic.ServiceBody{ + NameToPush: "vibu.testsvc", + APIName: "mytestapi", + RestAPIID: *route.ID, + URL: "https://myapi.com", + Version: "v1", + Swagger: []byte(swagger), + Tags: map[string]interface{}{"tag": nil}, + AgentMode: config.PublishToEnvironmentAndCatalog, + CreatedBy: "me", + Status: apic.PublishedStatus, + ServiceAttributes: map[string]string{"attr": "value"}, + AuthPolicy: info.APICPolicyName, + SubscriptionName: info.SchemaName, + } + + // + // Get the routeID and serviceID and pass them in here along with the ServiceBody + // If the routeID/serviceID have an key-auth plugin defined the right subscription + // will be defined + // + /* err = sm.PopulateSubscriptionParameters(*route.ID, *svc.ID, &sb) + if err != nil { + t.Fatalf("Failed due: %s", err) + } + */ + _, err = agent.GetCentralClient().PublishService(sb) + if err != nil { + t.Fatalf("Failed due: %s", err) + } + + // wait forever + for { + time.Sleep(time.Second) + } +} diff --git a/pkg/subscription/subscriptionmanager.go b/pkg/subscription/subscriptionmanager.go new file mode 100644 index 0000000..d1573a0 --- /dev/null +++ b/pkg/subscription/subscriptionmanager.go @@ -0,0 +1,221 @@ +package subscription + +import ( + "sync" + + "github.com/Axway/agent-sdk/pkg/apic" + "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" + "github.com/kong/go-kong/kong" + "github.com/sirupsen/logrus" +) + +var constructors = []func(*kong.Client) Handler{} + +func Register(constructor func(*kong.Client) Handler) { + constructors = append(constructors, constructor) +} + +// ConsumerInstanceGetter gets a consumer instance by id. +type ConsumerInstanceGetter interface { + GetConsumerInstanceByID(id string) (*v1alpha1.ConsumerInstance, error) +} + +// SubscriptionGetter gets the all the subscription in any of the states for the catalog item with id +type SubscriptionGetter interface { + GetSubscriptionsForCatalogItem(states []string, id string) ([]apic.CentralSubscription, error) +} + +type Info struct { + APICPolicyName string + SchemaName string +} + +var defaultInfo = Info{apic.Passthrough, ""} + +type Handler interface { + Schema() apic.SubscriptionSchema + Name() string + APICPolicy() string + IsApplicable(map[string]*kong.Plugin) bool + Subscribe(log logrus.FieldLogger, subs apic.Subscription) + Unsubscribe(log logrus.FieldLogger, subs apic.Subscription) +} + +// Manager handles the subscription aspects +type Manager struct { + log logrus.FieldLogger + handlers map[string]Handler + cig ConsumerInstanceGetter + sg SubscriptionGetter + dg *duplicateGuard + // plugins *kutil.Plugins +} + +func New(log logrus.FieldLogger, + cig ConsumerInstanceGetter, + sg SubscriptionGetter, + kc *kong.Client) *Manager { + handlers := make(map[string]Handler, len(constructors)) + + for _, c := range constructors { + h := c(kc) + handlers[h.Name()] = h + } + + return &Manager{ + // set supported subscription handlers + handlers: handlers, + cig: cig, + log: log, + sg: sg, + dg: &duplicateGuard{ + cache: map[string]interface{}{}, + lock: &sync.Mutex{}, + }, + } +} + +func (sm *Manager) Schemas() []apic.SubscriptionSchema { + res := make([]apic.SubscriptionSchema, 0, len(sm.handlers)) + for _, h := range sm.handlers { + res = append(res, h.Schema()) + } + + return res +} + +// GetSubscriptionInfo returns the appropriate Info for the given set of plugins +func (sm *Manager) GetSubscriptionInfo(plugins map[string]*kong.Plugin) Info { + + for _, h := range sm.handlers { + if h.IsApplicable(plugins) { + return Info{APICPolicyName: h.APICPolicy(), SchemaName: h.Name()} + } + } + return defaultInfo +} + +func (sm *Manager) ValidateSubscription(subscription apic.Subscription) bool { + if sm.dg.markActive(subscription.GetID()) { + sm.log.Info("duplicate subscription event; already handling subscription") + return false + } + + return true +} + +type duplicateGuard struct { + cache map[string]interface{} + lock *sync.Mutex +} + +// markActive returns +func (dg *duplicateGuard) markActive(id string) bool { + dg.lock.Lock() + defer dg.lock.Unlock() + if _, ok := dg.cache[id]; ok { + return true + } + + dg.cache[id] = true + + return false +} + +// markActive returns +func (dg *duplicateGuard) markInactive(id string) bool { + dg.lock.Lock() + defer dg.lock.Unlock() + + delete(dg.cache, id) + return false +} + +func (sm *Manager) checkSubscriptionState(subscriptionID, catalogItemID, subscriptionState string) (bool, error) { + + subs, err := sm.sg.GetSubscriptionsForCatalogItem([]string{string(subscriptionState)}, catalogItemID) + if err != nil { + return false, err + } + + for _, sub := range subs { + if sub.GetID() == subscriptionID { + return true, nil + } + } + + return false, nil +} + +func (sm *Manager) ProcessSubscribe(subscription apic.Subscription) { + defer sm.dg.markInactive(subscription.GetID()) + log := sm.log. + WithField("subscriptionID", subscription.GetID()). + WithField("catalogItemID", subscription.GetCatalogItemID()). + WithField("remoteID", subscription.GetRemoteAPIID()). + WithField("consumerInstanceID", subscription.GetApicID()) + + isApproved, err := sm.checkSubscriptionState(subscription.GetID(), subscription.GetCatalogItemID(), string(apic.SubscriptionApproved)) + if err != nil { + log.WithError(err).Error("Failed to verify subscription state") + return + } + + if !isApproved { + log.Info("Subscription not in approved state. Nothing to do") + return + } + + log.Info("Processing subscription") + + ci, err := sm.cig.GetConsumerInstanceByID(subscription.GetApicID()) + if err != nil { + log.WithError(err).Error("Failed to fetch consumer instance") + return + } + + if h, ok := sm.handlers[ci.Spec.Subscription.SubscriptionDefinition]; ok { + h.Subscribe(log.WithField("handler", h.Name()), subscription) + } else { + log.Info("No known handler for type: ", ci.Spec.Subscription.SubscriptionDefinition) + } +} + +func (sm *Manager) ProcessUnsubscribe(subscription apic.Subscription) { + defer sm.dg.markInactive(subscription.GetID()) + + log := sm.log. + WithField("subscriptionID", subscription.GetID()). + WithField("catalogItemID", subscription.GetCatalogItemID()). + WithField("remoteID", subscription.GetRemoteAPIID()). + WithField("consumerInstanceID", subscription.GetApicID()) + + if sm.dg.markActive(subscription.GetID()) { + sm.log.Info("duplicate subscription event; already handling subscription") + } + isUnsubscribeInitiated, err := sm.checkSubscriptionState(subscription.GetID(), subscription.GetCatalogItemID(), string(apic.SubscriptionUnsubscribeInitiated)) + if err != nil { + log.WithError(err).Error("Failed to verify subscription state") + return + } + + if !isUnsubscribeInitiated { + log.Info("Subscription not in unsubscribe initiated state. Nothing to do") + return + } + + log.Info("Removing subscription") + + ci, err := sm.cig.GetConsumerInstanceByID(subscription.GetApicID()) + if err != nil { + log.WithError(err).Error("Failed to fetch consumer instance") + return + } + + if h, ok := sm.handlers[ci.Spec.Subscription.SubscriptionDefinition]; ok { + h.Unsubscribe(log.WithField("handler", h.Name()), subscription) + + } else { + log.Info("No known handler for type: ", ci.Spec.Subscription.SubscriptionDefinition) + } +} diff --git a/png/KongAgentHTTP.png b/png/KongAgentHTTP.png new file mode 100644 index 0000000000000000000000000000000000000000..f9298fc1fbd572c504d27220c9dd90144b56a8f6 GIT binary patch literal 106465 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

asR|lxHpAIm z;P~9E1NJgNStEMWPcU%&1)$UFse$LB7s}t0q2Pd!_P=EFJv3(RKEJjCyR6i@!zOtj z<-ryn4D3_4TD1>-ZPVU&o*udSnH&|x5?j|vZ2-wXlAAdA1HWQk`M@1 zrrTBbwqFlvJ?7ILO8#hK=j`vTK|NcjI|GIvBI*gd8p;UV;vv-TD^;g^CFxRN-J81k zB|&fuuk%@c_Od`e6N$q9{m`?or9*r>7y0W0=};hk5KSPHOxw>g$%T6j2P|HLvlgtn zR{L+F>R7ww_ons{PQYqg4E7RuKz_AhkO)N{YXf*61Ii;|Pl1e@4;=blRU0v#mp}4vjx?g~K#n&|hyS+V)lz^^ zUY&SPic^`-0UDp$g;WA?v0f%_f(5wB&*KRl%*8wqk~kR4L0*2UBxr^N+r z84br0bMgHHkU$AO-#Vuif}m1PSm-5)+p3B+^2dPq^s>Rc0&};m{zRMkttQbWJ2=c! zvS7sw6f-59d;7>9Yf$gbcia-eJ@-fPE10Ga=Ep|Gr=C-4u(lf;u3=p#6^8 zgTXregh|2mO(k%7?9n$3O6!9&k$dM8Fp%xs>5JHbHZbg~-eUo+TkSntc!+S&fLHR& z4}>4zaaPeIldzH>vY8q70Q+UEYsk4ji5bj4UsPlGqP zp7p5GC=Xq(o^Se~0l$q2QTw{K2X=}f!)2IPaR5D3!n!{+AaW7+nRD$x7RtpMSjDpR zgq}I}_PAuxcpL1d;0+)+OhZXjNHF>7o{xhJO_eb&7#M)7Me505zu^~%^lx#2k1A0l z;gSsaCYr%Oecn6vCQSia=bu)5bF22}X!qvsu&^&bbN@r(3JCFAkRMh^}}%4ZuVxdVS!nKO({Ggo)(wfJ|QFN zk_}f=Lcp9^@ZQGbImqIT5wjUz9?UKQqt+v2XHhA9IPRp7;0Zz)++e!K!g|3hk02!M zEi(^YbERV#3c*;l~XqNJ9Y+DV;jGZ z!cws`#FFE=h4>FwWOE<@A5W3|5hZ6+PeYPR+urH@Efup%zJE;v7av&8D6CUZf=>|T z?!Pjdw$oZtpoa);k>#HA<+=IBV=t8I%1z8rxGv z7bBo{dL^$L*v%JvVMNjqtrW4>8lkSuHF5=zo-chLba0*I#A$m-0eFXiNk{}f)riv9 zU!<*7ym2x8reyNzr5Zzr8{Nnx0hLvWS>}!SqDr(WX!?~y^C)~a?=!n~x-d@?KtJgO zEdo$rx{wp(Wkc8Y>q^<_5udJPfS(YOi;eG?{x$UAwh3i!j1GN+AhAm6c$q1u6>5R^p%&7Fy}2C&-;}@B+uox0HyP6O&fn><$*SHY#HG1&1H? zgU$&4kT|ldZNkb*aDHUZ35emt#q-uyP8!%@V^G+TiqOVDzr!&w;iMGuyzdD?LN?Tr_$PnitCfIF(UGLn z*H4{;24xV0)j0+|c54KLrtlrxm#jy+2@KV)LeiJ;;T16lKRi{q)Asx$8n3ny0US}y z=STfE&PtoA+i^ztmhHUM*8IrH6&ymwSEMfxzo*ca$SlE7(!!hS7ybJA}Rp1^d~ zy_TEDPCf1`-1=mn!k^m~o1w6aFQk4RmbT!{ zJ!&Kb=Bo7B?BJgB)7Nj^{e`s8k7=}nZusj=d46B(*|THeGpxFu?}uQ%()XpvCJjfw z*GmEaB2Caf@C4h>2_Pj6U$Z`8+kF&-x;|B9;G(0yL;|P@NFK63fXl?EP1J8&Hb<0% z3or-e=dIWyH*b@bcJ6Cl0vh9jqRY~ua9}P;^5Lq`*4;on&i~L%Ziah?zx29h18jPq z%2!u2pg!Nx1!(2r&zdfu;uor(3bq;x^QW6AwiU+PBdzd#1y2(yL99%06D5A{Ii!w* z#4l}rp+GY{4A44^j74@8X#0A^ZuJ4h<*Q39ktwP9L&7Vpu`0)~)9~;g{?mMf`>+5% z84oo=i?SL@!7lv`VlHzUK-<`Hcs2?apbr;_F7EM)tGVH@U6Qlr_X~~|DFx5O2y(xM zE(5+1qznVV6Z#{QdVrlN$Isu21*sYCK6l(H)GtQ1q+hFRN?VblLKyhfGV^2Xc;Km} zpITjqQQpR73*g1>RoezQ*0dk{?mZ2Nj9tAwq2JhmryAtr2RTiey<_-OYxy1(p`rQL zd_NzmQ%^`-u^%74c(0@1IZl0YMzG!$`8*JORjjm%!gzV!TfZ#)93eoDY1R1v^052^ zY#+|Rx_&Glu=;0KoO@~8jeCKI`;Qk3LJB}9zEVAV*BBSQ23oLX=*^+|mJngE=dTzn zM~e_}0JxljK3FoT4u+Vt&yPTtA_oiu|2>07F*iO6qOeF_DLB&g9tVAg$ezMdz#`E>1yRleGytzeKG3BhII0he z$^GGZRu4djs`TH-7L+iAVEpi!y#B^pMksYVmbK$f1mNs+{!i)d^BpD(RWex_M*tD_v(_|2r^Ys5-UA<@G#2kA zd#A*M_oJ}OT408zm`(zJo{%>U1P$!iR>;t4WIBicCnvTh!b|!SvEAY}5b?dEOr|673I-0xWktSSb$>gH zL7D&Mo%sH6H{z^Y#Az*&CD(P}IGaJyXrUJ?|ZIDY&~C!qF;!nZWUwky%fVhh z;j;Bd+m}d?&Ax*~_@DFWx;?UBUNh~D3p-_%P+gPXO$rN(WZ6-R{@`c;1^ot)KkD#$ zxShdJG^GFULmVG}RlrV^+s{b4k4}Ys2B_mlk7iw5LBL#?$T@rg#RYk-G!m7T&sH(n zSz6EvZnJiIR(zK3g8Tc~@xooP)j6IXGPMhp0OB&Q)C)R3j1Yy_Vn8?kc;Zg&?7aqg zwG{zplycB30P(x}+V8MaOZ?g(>PL~cxNV?8kW6J8+GJXJMIFtb_9Th+(Ty9(4JRnt z+!-e6eFpwSKhNo5BL-FhJ>5hGBY2`O13Xp8+uT?Jr(PM^E<$S=K%5f}pF)EHejfGd z21@90kbHW=k>toeB8*l3xlwh6kwtpQ7ixT5xruDv^5D{#>??;ei+V+PDfhqfDR?km z06Se9l#QZz16+*GFP_sH22*g0-mB$<5hk>UU8h8Z-UO{m4cmMaZ@u?KVVbr{_J;TN zQf>peOIw)v5e4hKH95Uf%;nagH0oQzrO?*yF8W!R z-cA6&dVv$)YvzQWpx=A#^zP^WR4TYReJ6)prVQw*A0q8hV+mDd(mC#uvjNpC$%NLz80&|K%~%LT1Qiew}A8Gw3F zhEqtE$Jy+oOlIoOby9&6+d4=tq}7hf08kkh@Z0;e-8Zw=;#;k<)hHikNT|>k0xHyF z^x?TmFxR1ba|5pMZ-3sQDo-kUa=(l!))`pFsd5AMFu$f!8)$)&UR8{E$-S3Cci#iR zA-7tM5Z|k;Ch~&kjg@F}W9a!Z8YrlKpT=oi1^02cEGKgGQPX zWQ|L4zPD?{O+%L2{YBx=OkOjfwK0J!e5&V!1UTD4GIH_tUIKdk2oORY2dFEk*n(6* zFYbvdF4(s}!v)Hw85Mzc;xnr+4z%30ZG0MlAwqqfiFrI)6ThHG?M&f~J($sdsa7KF zj~`UWevI%yx9xrZs@VQNwme4<*4~L02x5BW{XL*pOs|EtkT;nCWP@umGu$3LA+$176($YSjd?k9Ejfa3};9 zbO*x7TiODD(%=DX(OUuSxKJ2~6DStegyUJ?dUyqNE`#C3C{=$BNpKa1@~|&>6xyj- zXVr;{Y6ubx3MID3@%2fL0wFrIQXD{|7kRI!)L-e)$9kC9=~fEi+zuab(0n2Rq^n@} z!WW%%mI;&_qPN{!8a(;_`MlikFxsDAX|wcwD}{DY5eo*XF#u3PV6S}k-uWR6IOY}( z958q*HFFC`pqB-YmqDfE&*KV%U$;0l)2A);TmT{K5ux@Y4`-wY6S-YLw6g-(ty*-d z5EfMv`KH)%?1TI)FVuy1B6<4zr(9qz0P}-C8TbSGko<^^1*;?34$q5P-2%A;XFS;v z)>_-6FFLt3P0gM4|2xzA@>)c6quk1(ztUV8HagXFUya-yJ z=3&HJz)bOPF!P>ickoqE-R`Qra-T@qwg`Gt_L*B;8D z%q@^pAK|76sOUtl?yjLKe_b{wKt|GJknBVQ0>>OIg@pH8&@2-z<3LBixuS=bVPBC18XQ={ z1*cxSn^OnySg3=ifHUz<%{r-I0Sl#d|njvlA( zY=aV20WE*YI7R9d4cr}la_ImHeuju)I>Fbw{aWD!FYE2k59euua}4B90*oTKZDWaJ zLs*aBRaSkx>O0r!Ew-WNWNUm3`N7_|@aJjHvHEx}ySM%AW{C76ARw=bO*jCh=)7pF zJw%{;-YXXM}z^pch3W3f{;rax)Dg0)Et|Ft!FYD*;recdMaGNXZ0m4{tWmh#3 zU$y{5(T{t{KhKU({9-loEa-J#e2;K#cn)I|CD58I+@JE2`jrdyFK4l$H>7xZwdpdR zI99!Y1%^lCIs*)xcve6&gep$I!;Mec_(Q1s@P{_Z{RbEXk>uXgw4j^?B=#8C%5pZIrha!t!{>3ood^HULmUQc-h6uhn z%U8{Lp*ya3B(Jp>LMOZ*F#g&*&|R>yPZ+BF0)gMom+AvnZ^Se+*tjT=gMw)cp^gx# zCv^=D^`cMc@31aB#wyAIgU9hN%iTm&JRtq@cS5kYp9=ZJo zxzq2*M<8ERa;}^ZLSzXPtZbHmTx3$ci{(;+pS}d!#S7S(qc=x*+x=QF%~9m8Rzco{ zd{^o_BR*AW+<6aM?*wWbm?p>*sa8yE!^vQb!>oZ_IyEE$>+2GLLHd*EKzzMvmg4r1 zYyGLP_42*qb1y+0BS>ARoo-iv%m#Li$Ml6wZX#KOOlHf$H#eY(#|dfV$t*s~zCajy zuRL%d;1`f2K=(D-fZ4Zpgm9j^xaI+1n&(|L=D|A-vv42SXCROCTf*;%BDX%|=j~cj zvJOl^-^-ZbLnm9Afa8d-ae*d0+Ah(G=)r+J7+#3(@52M!FR+FMdT0eTGrUEa0r-gD z-;NyQ85q(t2OQH(E9s>t2gCr3sk0C8uG>$tNC(q+)TG~A*zOL~v&nXj{9(W330q?2 z@;d!Uoa_?X>yFD`)4^&tc#z-h>i2>dA3rC0|MxxmHJC`=fjCso1yZ0p?L@Guvw&@u zf|*BW?t|LgAq=1dI`RBvso(nW6nsOiX?pKv`3sg#%zOb#N3P-%^-&W*IWLBot>1(=k_q@jQ~pZ<6RdT=^AoCFL&Fb^l*AOR)@nPoHV>ssAhD) zS$^A6_4qMi*5RPL)*Juj+B)J*+v|AMPk`(Uk&;8ho_gYG^2Mk4@jGNY6i@x3K$)j! zf3KzR0c{jCBsGoTIyAKp^BHYtCc1%|ZVM3lUcGqwrO*Jt%)GCfSG|Sj#nx-cmfs7B z-P%O;w9;1VTmT6|omVh^EUd{-$PGXSx-Qkys@sWcseI`{eLF^;qrpK-T7q3Gy4NRv zkkI_5yw0cpM5B#JjxDk)!k7)AzCUeG`Qc_gSnCCBPnvBxmNO+aYFFs z>pfG(hoK@xm?wv@R+j9YC&%3pHE=|W5uv`gD!5nrv%D$ z3jllu8QHm)A_MA(V3Kor)mP(pqPVsnz}=;X#b>9~)@Uc{ zA^-cHLX~y!aFRhvVx*{oy3A1T@;#d|bip3kF`ul+O zfo1;Q7q-HO*wG(3g9iH_F*4~MGWL9+dEbgB^wMW9;gm6hc^Lg^UiNRB-wOL2|0C(T zwiAV-=r5u4N4g+VMT9q`3MhzDzkW8EwK64!0OBpD?DE`H?#fMw5)SPl#)Mjv^Wk0- zXZ2Zyr|*1GhVDo1-atn@5f%CdnHD4`XK18Xrs=qbnrn8WTc3%gbM}!&>B<<+z2#e! zP3UaK0eYCiWR;9=@q15T{g`|@X-1XqiEPivN!qahj?`Fm=}*u4|xpZ z*}q+AdyK!H;*#Pw-E=ah?>Q6u@g=aQd82K=Q@oRHXs?>`S6?CKFnB!tUSR-PYT+z7 z%=a&y8#^;tw1Yve8Sl{<;9kNb#k(m#>v`G&SEBBZ9Chs$mV3G8Jck2J#JmsT{}eS1 zp}QMqyZwz=G0$O(Iep~SSI&0!!Wv)SIylGb^eoEa+<)($7R<$as&s;74s#S~lhfAz z$N%gf8F4LV=kXA~4fT``-z@Lq`5t)S{Y!&{32Q((Xp)2&db1D{u8T68n=jHb?LEJj zjfQ63BWWoLFz|X*zI&tx;WeDM*Pg1YY^F6`&>%U;P7$On8dd=AVavh@@wqJ)PqDs9 zJ|}taoo}OZdmmdR@rStsUgrbvJU*Y)YeXH&?DqAd&l^Uqj)!)X@3{o?qf0~Y4X=Zu z)-TLc(HTxu3Tv!-sS}3MPsxYbf4mQksDMrD%>+dDF>V#vT!Zn zNbONG_qvO+J-pr#lIPh^BIhn zKiBW1Un4D04mu}CyZ@)^o$(iU9e|+*PR6ZsA*w#*Rl8Cu@F0RYd++Dv<6wG^wD9@D z>)M$$%e~uzZ$M5H+6|I!W%5(G*|KgjF#1)(=tWqMhdlf0l{sBls)R_P3ZR2!iV3d@ z?{mUg9RMg#++;5}_r8klil^=c;amgmE2!!`*(*=iTDvZnMhzap4|M*MX=U2?l+0gf zLgTI>D`{arkw%4!(Q`3i3&VY~x4P@PitKW<(Q^YD`w1`OY5Lq#g11N-=yO_B{Jpne zj`W+{o{)7Dzw?rK%r^zDh{VV~7&4p?ba8nx5ek>C^T4g5zA_KdJcX|Pa5G|{dg7X3 zGZ7^!gpd)0OESJyO3s+}5yG!o(@NQT<@Vtx+Vp=fH~(~;=ns;4Hw0n@vdd6tsmBoJ zV?bhoo3%s*SFN(6z%*HhWQ{DI+GcdDFzg>4+>mi*`Ig=4`0bSQx;I&p!R%x9K0FF^ zh4isOnM$gt>Bu)N2om4qbHDy!8dmnXZrjBRYl7|`K7aBrltj|h<@63}?uQ=C2|h4b z0@NbKgj2n&`JAqQlf)6zePib+p==SJ;J@1*KzhgJaY`TjMKH~GWN(T9L^@AEh*kU< z4Fo31HyvQ20JpY$e>Qc#Ki>>WQq0q_>o+nF)mx0N-=p7Zs@7EqHk)Rm)}@j%&|>+2ZtJ%041P2 zlS6`}`u3#YXUO2x;g-LdM=xKl)?3QlD!MhajyRqHX)sQ{k{6FmoF-r1W8DY-%;v{K zJq)PH`+ehr4i`caf_ZBTjgZVSVV%IsDv%)*#9+LlUq!R z$sD!AeQv$Qx=IQVQa_#Ld|^qj9AD9B@dm!QBRa7V_pI9yuHSF2bTjf$0mC~Fo^vAB zHiS4$k-cA;ipJepBMyhh~S%MXrN z5Db%g|3$9?2na=swMd6330iLIA)=hGf)>`1yt0rXN7QnX5Nv8MtORd|4R&g+H%J zZ79&eoBVzG_}Zd*m9%Z!64+hE!56#RJ4t6quiz$XGaowlmh}!+2hk_f>3JK}=8)K* zD>o$N#l-?a$Es@D@kTBj2Xz<($=PjquJyAZllR(1qHVMg$QDRjO= zhAOoVX%jOr(R)m5=4-KNXz(uymuIb?NFRb!$qKa1&>dW-ks;utI*;(=?G@-5&JT;Ny7G?-(jmI? zCk3p`$fAm{@ksEUOu8IC;I77i96~%~Hc~rT364BTb@hM_*I0$2jQUqZ+<3R(<-?PC z-!s+V^*GvBW~@lyYL`85o7c=R^`So!PWpY%S@S-|NlG>$c~S#sX|oQoHdt_bD8WNx zD=t2TyGPRo&xJ@8Af0@Lhxdc4`Dza|=;RTkb@*d_fWob^>xMXbI_u^jYhdY9bLovh zmFi=6;phnH2*}BEfBN4>kvj8|o>%k6i>+^aXUBtJEFm6_NBXIK)h1zw`1qiM2TPoi zlWaGYyY7L;9u#zI zd^o<}qo;7osqtz1E;=(A*MwHodupsoC;r8Nz-*h*JHeZVfBXFTmPul1H-S1V$BF7B z;W9HPT(CQdG~yHFb0&MN>*)+B7{m@_NC5{cSY)L6)M%&i{2=57u?3odU)ipD<|55h zh1SRw&DsNmghRNIbK>ct>XO!rcgU&B<;Uxe0rgy9zHa>3I8ZbF7#eE}Ek?~FB^xEy zJv!>s1FxX{~^Usuk|8oFceFl>g^`MD_4lWiXOJwOsPxYJ}0Z;Sx`KS8kh z9R|}>P9N>BY ztYaTAWR^q?Z9MyN)NXHN+(O~Mn|R;ChHJVM_kBZEjF8N)11h_!+sor}`p88;7P`?DFpfUdj-R}lOuK(zkrs@1`&=LHR^>wa zE&a>{=bSxph7$?($?k3U%+eNUz5N-BWmF!EAN8m1f2@R0NnO0XeA`=(K{?7{Rl!_R z3HpBQK2xJqFcioSRN45qQ`5K??4n;17=qc-b{z2A9U9`;YAH0`4r_1~v<`+0f1Y*q zp+J##HT8z9v-lbr|V?h%ge#yq}xi9 z6N?U7Um)YTRKmFe8|BPh;8(+MLaw2&*u^ZUitNCGU)y8dR2Pk5KbKL-3ejSd)!2C|15nlTbxYh_K| z1(3qQtQYfp$hrYxqy586((4FBjekiMO%;?_5$0zJFJ?b^{E|E@VqmCUoEbT6k9L+S z?a7Nrh@@wfp(+=H(VZ0{lR#?v50MjLTJLf=6n!oAB*f0 zVmq{P5Eix6uV-sE$@MP98c!z5AtQ9{ylT-0iQj4cl=#GN#cp zP2!p=FOSe@>RQII(F%I`d#IXO8H-r7ful0bW=-FU@DHik#|vx+`%tLrT6pO6op|XI zYct)N2wb3CUz~n^#^QajUpx~P98h#HhP%XKs^8&|2i^sKNbn~((>2p}bl3?D9HE*L z*wp(a6AW$(2dvYmXD}piAwZAHtkL(r3S&1|n0(VU_jTRB+rrvCZ>Wm#;rBL83T2svkLekee&zM{2-?NQgQ2EanAYSNPlj(_-Y#Sz(0Qy2_ubD_$dGKPa0Yzzp-9bO)t<4 zrN&pRcfWyLv+Z)Khz+n4;jMmy8I>YMV7QD6U}wz%FACd1r9aFnF^uc+m-O;aO8RYI zF3G&B5c8_nnccTU3)sjLS^uyus7G&t`4E5P%t&%lb}4fE2_TmB**8AVBz6>}YJNs| z?L~u!)Dm_u)TJ-s=B0@~m)%!KuNGtZL=zRVhi&b)?qW_EJ8 zoAc0irYI4Vt<4l-rof{U(VI^yx#Ud#%215qU7&+i_~f`RCsuIS;2ZcrrX4NUqKqYa z6|oS+9~PRj(T@^=Gg*e{*ZYqau!9-~+`maQS6E3I7wVE38FMl8!<@flETk&G6tO8E zz`>++mnbeN6T8NH_1^kvQJkoERBbQy+IvRB4~KD8&m38u4?TOz_l4M~qKHSH<8V4&}Ve|!1DY%M#zTB_dP?B@h;MNN5$CI8nEq0aB8 zJa}=@5rVRPS>A^1z4Tb%b}FvXS=V)-tedZFqo42>0}61 z8@!Hd}=)Aq%eR-lmisLp|o9O2BEXJjR;T9pn z@T1FX4Q4L<`kGRqKQworogKBaB}_4QL&PG+ngsD>zNewr$BaaJIKA}tb|ZjeguaK&u;kUwDzGQdmP{K~8EN}I z-@~Pkn#ZL-fPK~7?!#x>V;C&$`1=~dus1J+n;50iFZ40z@v6b@wYX=BFh8tYoL_$?mG!}X&>^&!Z-Tcf@P zOILz`gLz~-9kx(oLk&03Ly0BRKGh;sVoRx5Bs{s9)GZ8IKld^zwHw=DlEIwUJ2Y{ z(voA=Z1-3Fy&difV2b8{7yxM&?~K{m_-e|VViS4t^wJ;3dauvU z#ZZEaL96S1yZIMl^gtohr^6kcVdV!ja?^TLre3C-#c7-=gep1H{q{*z*g=%jV2S2^ z3ciK&C9j_s-?e452e#q?fK4k-TnUSa_=MT@HTQz5)YFE;k(DNPJKN6R9*Oa zmPNOugoh{3MTl`si==$=#NnRI@`yS(oKsITo; zX7Yp5?L{x=*?!kskH#5ncB%anQ6r%hO2Z|Nm#@rGIUGvjDS}7zkZ)=;f$0diO==lV zr5`}DNv<}OuX#=uZF6jBq66v#O>@<3l!QN<#}5ZPmwgrzBs?9Jc#p%($+NZVzG~1l z$-0FCm0K0I5%hCHz@$I(TUxJGy^lQR^tdd0t5l34Pt;zm^48D4xv97PjV=I(M{AMS zNoo|%ZTKvu(@I}uzn*1)l_}+i!;oGxDiEK7ct-Z>z7-TlctF_!`x5=!q+QauvBijQ z&5#5HG*B})fk`i3#tT&I;9;D}IN+)FZbS$wNK53}`xLf!KqJ?a5{|!OS^aE^eGam` zdDHj?*-aJyq3+=Gkat3!X!0X8RABhdYdBwSTvFZzxFNKqD$LR+d20uhZA#M@+rU>H zwC)(qX!pS-it6?|lhCUVm6^A_74|ywnA;3pO|;EE4<}lTXJ=h`79JAWm1Rb7mp#*6 z826`*F%bJ$Xy~s=em}^rX_|GqeXURKuu2>*<6M!+dk?j*xR^sw^R)qw9RfigWDA$> z3XSdk$z0W;R(NJQT->WWJFG-%93MVzHQn5!$<<;y z_hW&cKREwn>j`_lhsp0}3-em>JV0Av+=QmgNpKbXjK#hj;K;drKZ!vC(AqWqY^RWl zVKyE<=MF{b!?K-6cYBQ|3>W9~K7r=)GxWPuenIa)E9IGf6l)_(W5a()r>XXL;FC;R znw)h`Pr@D)$U2-!4iUH`=LrEdXRTU(7<_H~yz|#Bx$@7uw28&&K;(+{pnEVst{O!_ zISru82`AVP8uaR&4*{$Mo<$U@>lzSrW&P1&zV`U4pSL&msp$*hI|IKFIX^yEEemxH z+z?y`;D@MOtzU^=zSME_rl$tt^1@VK*P|Q^178nW0v|iT7a$BgMGGX#JMlMo{xiV& z-1d#OMZ7$;spXYZQM*|dQ6}G*e+Ho!z{PbO_5{ePADi!n^mq?V*Vn;6>-G1b&O^U%ht%oLd54dc&36bO+L7>%KH#IaLbCfRiAZCA&rDxqGATNg zdCzb5tc+|E#$PBLf7~A8K4x-i!@01~Q=X>n3s&T~{h&bY1sp_GEADhZgFhY zVZZ+PG1l-X5gI2U_-f91c^ur!b$;J#PK8M7k6I;xYrnG|TYx17)aPjMg1eaeo2(?m zG=AKDUss#alVwgWggyhgMWt!D{YsB=d?Y6Y?FKaS`q6&+#B~P7>BbG(=z=s;NYXco zK?TPdG-!1A?+n{KzCp!`fECglovpl5?%Q(}j16`5i!Vqlxf{r&TV7cc(ELk>%&z)>si?${E&E`-6tiKQvE~KX zLqg&RP6xQWXx|?%EVb!AMBL{t-=hxU?O2~~-agw8pVwoY+1ofof_2-Av!b1{g!D#x zTzj7SIx02O9n4$m6p|*V5I)k5p23}KB4SvDhQ;*ha@B8ijv9=&!I!tjpoAJXQ*3W& z9(2y>SHJ7`q28@2#TJ;&?JFN&mYYjGrLpd@kXuQ6Ij6(5f@PE1S#o5m!ukm%(IJQX zhMEgCU5NUZ7d2CPVG6|MJ%MGh`2)5aoA@7)XgHVVJCzgDp&{&>tG)1!6D`S`RzL^f z4466�}JYpn`O&?0xADgJkm*`R$7b2Tea0zK_@Or$eOs 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 P1U#Oo>p?12t>63) Date: Thu, 4 Feb 2021 11:21:39 -0700 Subject: [PATCH 14/76] Look up cached services by kong-service-id attribute (#5) --- kong_traceability_agent.yml | 49 ----------------------- pkg/gateway/cache.go | 2 +- pkg/gateway/client.go | 37 +++++++++-------- pkg/kong/specmanager/localdir/localdir.go | 9 +++-- 4 files changed, 26 insertions(+), 71 deletions(-) delete mode 100644 kong_traceability_agent.yml diff --git a/kong_traceability_agent.yml b/kong_traceability_agent.yml deleted file mode 100644 index 4c75dfd..0000000 --- a/kong_traceability_agent.yml +++ /dev/null @@ -1,49 +0,0 @@ -kong_traceability_agent: - central: - environment: kong-traceability-test - organizationID: 251204211014979 - platformURL: https://platform.axway.com - pollInterval: 20s - team: "Default Team" - url: https://apicentral.axway.com - auth: - clientID: DOSA_9f07ebffe9ab48cc8f8c7206f0fbc06b - privateKey: private_key.pem - publicKey: public_key.pem - realm: Broker - timeout: 20s - url: https://login.axway.com/auth - ssl: - minVersion: ${CENTRAL_SSL_MINVERSION:"TLS1.2"} - maxVersion: ${CENTRAL_SSL_MAXVERSION:"TLS1.3"} - nextProtos: ${CENTRAL_SSL_NEXTPROTOS:[]} - cipherSuites: ${CENTRAL_SSL_CIPHERSUITES:["ECDHE-ECDSA-AES-256-GCM-SHA384", "ECDHE-RSA-AES-256-GCM-SHA384", "ECDHE-ECDSA-CHACHA20-POLY1305", "ECDHE-RSA-CHACHA20-POLY1305", "ECDHE-ECDSA-AES-128-GCM-SHA256", "ECDHE-RSA-AES-128-GCM-SHA256", "ECDHE-ECDSA-AES-128-CBC-SHA256", "ECDHE-RSA-AES-128-CBC-SHA256"]} - insecureSkipVerify: ${CENTRAL_SSL_INSECURESKIPVERIFY:false} - -# Condor Ingestion service -output.traceability: - compression_level: ${TRACEABILITY_COMPRESSIONLEVEL:3} - enabled: true - hosts: - - ${TRACEABILITY_HOST:"ingestion-lumberjack.datasearch.axway.com:453"} - protocol: ${TRACEABILITY_PROTOCOL:"tcp"} - ssl: - enabled: true - verification_mode: full - cipher_suites: - - "ECDHE-ECDSA-AES-128-GCM-SHA256" - - "ECDHE-ECDSA-AES-256-GCM-SHA384" - - "ECDHE-ECDSA-CHACHA20-POLY1305" - - "ECDHE-RSA-AES-128-CBC-SHA256" - - "ECDHE-RSA-AES-128-GCM-SHA256" - - "ECDHE-RSA-AES-256-GCM-SHA384" - - "ECDHE-RSA-CHACHA20-POLY1205" - worker: 1 - pipelining: 0 - proxy_url: ${TRACEABILITY_PROXYURL:""} - -logging: - metrics: - enabled: false - to_stderr: true - level: ${LOG_LEVEL:"debug"} diff --git a/pkg/gateway/cache.go b/pkg/gateway/cache.go index 9770f37..d5385c7 100644 --- a/pkg/gateway/cache.go +++ b/pkg/gateway/cache.go @@ -44,7 +44,7 @@ func initCache(centralAPIServices []*v1alpha1.APIService) { clearCache() log.Info("Init the cache") for _, apiSvc := range centralAPIServices { - setCachedService(apiSvc.Attributes[externalAPIID], apiSvc.Title, apiSvc.Attributes[kongHash], apiSvc.Name) + setCachedService(apiSvc.Attributes[kongServiceID], apiSvc.Title, apiSvc.Attributes[kongHash], apiSvc.Name) } } diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 3c034fe..38b47d6 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -28,7 +28,7 @@ import ( ) const kongHash = "kong-hash" -const externalAPIID = "externalAPIID" +const kongServiceID = "kong-service-id" func NewClient(agentConfig config.AgentConfig) (*Client, error) { kongGatewayConfig := agentConfig.KongGatewayCfg @@ -132,23 +132,8 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se if err != nil { return err } - - // delete services that have no routes if len(routes) == 0 { - log.Warnf("kong service '%s' has no routes. Attempting to delete the service from central", *service.Name) - item, _ := cache.GetCache().Get(*service.ID) - - if svc, ok := item.(CachedService); ok { - err := gc.apicClient.deleteCentralAPIService(svc) - - if err != nil { - log.Errorf("failed to delete service '%' from central: %s", err) - } else { - log.Warnf("deleted Kong service '%s' from central", *service.Name) - } - - cache.GetCache().Delete(*service.ID) - } + gc.deleteCentralService(*service.ID, *service.Name) return nil } @@ -192,6 +177,23 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se return nil } +func (gc *Client) deleteCentralService(serviceID string, serviceName string) { + log.Warnf("kong service '%s' has no routes. Attempting to delete the service from central", serviceName) + item, _ := cache.GetCache().Get(serviceID) + + if svc, ok := item.(CachedService); ok { + err := gc.apicClient.deleteCentralAPIService(svc) + + if err != nil { + log.Errorf("failed to delete service '%' from central: %s", err) + } else { + log.Warnf("deleted Kong service '%s' from central", serviceName) + } + + cache.GetCache().Delete(serviceID) + } +} + func (gc *Client) processKongRoute(defaultHost string, route *klib.Route, httpPort, httpsPort int) []InstanceEndpoint { var endpoints []InstanceEndpoint if route == nil { @@ -240,6 +242,7 @@ func (gc *Client) processKongAPI( serviceBodyHash, _ := util.ComputeHash(serviceBody) hash := fmt.Sprintf("%v", serviceBodyHash) serviceBody.ServiceAttributes[kongHash] = hash + serviceBody.ServiceAttributes[kongServiceID] = *service.ID isCached := setCachedService(*service.ID, *service.Name, hash, serviceBody.APIName) if isCached { diff --git a/pkg/kong/specmanager/localdir/localdir.go b/pkg/kong/specmanager/localdir/localdir.go index 8eec522..d4a0a8e 100644 --- a/pkg/kong/specmanager/localdir/localdir.go +++ b/pkg/kong/specmanager/localdir/localdir.go @@ -3,13 +3,14 @@ package localdir import ( "context" "fmt" - "github.com/Axway/agent-sdk/pkg/util/log" - "github.com/Axway/agents-kong/pkg/kong/specmanager" - klib "github.com/kong/go-kong/kong" "io/ioutil" "os" "path" "strings" + + "github.com/Axway/agent-sdk/pkg/util/log" + "github.com/Axway/agents-kong/pkg/kong/specmanager" + klib "github.com/kong/go-kong/kong" ) const tagPrefix = "spec_local_" @@ -43,7 +44,7 @@ func (sc sourceConfig) GetSpecForService(ctx context.Context, service *klib.Serv return sc.loadSpecFile(name) } - log.Info("no specification tag found for service %s (%s)", *service.Name, *service.ID) + log.Infof("no specification tag found for service %s (%s)", *service.Name, *service.ID) return nil, nil } From b67829abdb00a7179e373131dfc5b286bdc7c7fc Mon Sep 17 00:00:00 2001 From: Martin Look Date: Thu, 4 Feb 2021 19:46:50 +0100 Subject: [PATCH 15/76] Use original Swagger from petstore.swagger.io --- specs/petstore.json | 1018 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 925 insertions(+), 93 deletions(-) diff --git a/specs/petstore.json b/specs/petstore.json index 8e3f0c3..c00d4bf 100644 --- a/specs/petstore.json +++ b/specs/petstore.json @@ -1,63 +1,274 @@ { "swagger": "2.0", "info": { - "version": "1.0.0", + "description": "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.", + "version": "1.0.5", "title": "Swagger Petstore", - "description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification", "termsOfService": "http://swagger.io/terms/", "contact": { - "name": "Swagger API Team" + "email": "apiteam@swagger.io" }, "license": { - "name": "MIT" + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" } }, "host": "petstore.swagger.io", - "basePath": "/api", + "basePath": "/v2", + "tags": [ + { + "name": "pet", + "description": "Everything about your Pets", + "externalDocs": { + "description": "Find out more", + "url": "http://swagger.io" + } + }, + { + "name": "store", + "description": "Access to Petstore orders" + }, + { + "name": "user", + "description": "Operations about user", + "externalDocs": { + "description": "Find out more about our store", + "url": "http://swagger.io" + } + } + ], "schemes": [ + "https", "http" ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], "paths": { - "/pets": { + "/pet/{petId}/uploadImage": { + "post": { + "tags": [ + "pet" + ], + "summary": "uploads an image", + "description": "", + "operationId": "uploadFile", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "parameters": [ + { + "name": "petId", + "in": "path", + "description": "ID of pet to update", + "required": true, + "type": "integer", + "format": "int64" + }, + { + "name": "additionalMetadata", + "in": "formData", + "description": "Additional data to pass to server", + "required": false, + "type": "string" + }, + { + "name": "file", + "in": "formData", + "description": "file to upload", + "required": false, + "type": "file" + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/ApiResponse" + } + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } + }, + "/pet": { + "post": { + "tags": [ + "pet" + ], + "summary": "Add a new pet to the store", + "description": "", + "operationId": "addPet", + "consumes": [ + "application/json", + "application/xml" + ], + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "Pet object that needs to be added to the store", + "required": true, + "schema": { + "$ref": "#/definitions/Pet" + } + } + ], + "responses": { + "405": { + "description": "Invalid input" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + }, + "put": { + "tags": [ + "pet" + ], + "summary": "Update an existing pet", + "description": "", + "operationId": "updatePet", + "consumes": [ + "application/json", + "application/xml" + ], + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "Pet object that needs to be added to the store", + "required": true, + "schema": { + "$ref": "#/definitions/Pet" + } + } + ], + "responses": { + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Pet not found" + }, + "405": { + "description": "Validation exception" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } + }, + "/pet/findByStatus": { "get": { - "description": "Returns all pets from the system that the user has access to", - "operationId": "findPets", + "tags": [ + "pet" + ], + "summary": "Finds Pets by status", + "description": "Multiple status values can be provided with comma separated strings", + "operationId": "findPetsByStatus", "produces": [ "application/json", - "application/xml", - "text/xml", - "text/html" + "application/xml" ], "parameters": [ { - "name": "tags", + "name": "status", "in": "query", - "description": "tags to filter by", - "required": false, + "description": "Status values that need to be considered for filter", + "required": true, "type": "array", "items": { - "type": "string" + "type": "string", + "enum": [ + "available", + "pending", + "sold" + ], + "default": "available" }, - "collectionFormat": "csv" + "collectionFormat": "multi" + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Pet" + } + } }, + "400": { + "description": "Invalid status value" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } + }, + "/pet/findByTags": { + "get": { + "tags": [ + "pet" + ], + "summary": "Finds Pets by tags", + "description": "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.", + "operationId": "findPetsByTags", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ { - "name": "limit", + "name": "tags", "in": "query", - "description": "maximum number of results to return", - "required": false, - "type": "integer", - "format": "int32" + "description": "Tags to filter by", + "required": true, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" } ], "responses": { "200": { - "description": "pet response", + "description": "successful operation", "schema": { "type": "array", "items": { @@ -65,158 +276,779 @@ } } }, - "default": { - "description": "unexpected error", + "400": { + "description": "Invalid tag value" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ], + "deprecated": true + } + }, + "/pet/{petId}": { + "get": { + "tags": [ + "pet" + ], + "summary": "Find pet by ID", + "description": "Returns a single pet", + "operationId": "getPetById", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "petId", + "in": "path", + "description": "ID of pet to return", + "required": true, + "type": "integer", + "format": "int64" + } + ], + "responses": { + "200": { + "description": "successful operation", "schema": { - "$ref": "#/definitions/ErrorModel" + "$ref": "#/definitions/Pet" } + }, + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Pet not found" } - } + }, + "security": [ + { + "api_key": [] + } + ] }, "post": { - "description": "Creates a new pet in the store. Duplicates are allowed", - "operationId": "addPet", + "tags": [ + "pet" + ], + "summary": "Updates a pet in the store with form data", + "description": "", + "operationId": "updatePetWithForm", + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "petId", + "in": "path", + "description": "ID of pet that needs to be updated", + "required": true, + "type": "integer", + "format": "int64" + }, + { + "name": "name", + "in": "formData", + "description": "Updated name of the pet", + "required": false, + "type": "string" + }, + { + "name": "status", + "in": "formData", + "description": "Updated status of the pet", + "required": false, + "type": "string" + } + ], + "responses": { + "405": { + "description": "Invalid input" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + }, + "delete": { + "tags": [ + "pet" + ], + "summary": "Deletes a pet", + "description": "", + "operationId": "deletePet", "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "api_key", + "in": "header", + "required": false, + "type": "string" + }, + { + "name": "petId", + "in": "path", + "description": "Pet id to delete", + "required": true, + "type": "integer", + "format": "int64" + } + ], + "responses": { + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Pet not found" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } + }, + "/store/order": { + "post": { + "tags": [ + "store" + ], + "summary": "Place an order for a pet", + "description": "", + "operationId": "placeOrder", + "consumes": [ "application/json" ], + "produces": [ + "application/json", + "application/xml" + ], "parameters": [ { - "name": "pet", "in": "body", - "description": "Pet to add to the store", + "name": "body", + "description": "order placed for purchasing the pet", "required": true, "schema": { - "$ref": "#/definitions/NewPet" + "$ref": "#/definitions/Order" } } ], "responses": { "200": { - "description": "pet response", + "description": "successful operation", "schema": { - "$ref": "#/definitions/Pet" + "$ref": "#/definitions/Order" } }, - "default": { - "description": "unexpected error", - "schema": { - "$ref": "#/definitions/ErrorModel" - } + "400": { + "description": "Invalid Order" } } } }, - "/pets/{id}": { + "/store/order/{orderId}": { "get": { - "description": "Returns a user based on a single ID, if the user does not have access to the pet", - "operationId": "findPetById", + "tags": [ + "store" + ], + "summary": "Find purchase order by ID", + "description": "For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions", + "operationId": "getOrderById", "produces": [ "application/json", - "application/xml", - "text/xml", - "text/html" + "application/xml" ], "parameters": [ { - "name": "id", + "name": "orderId", "in": "path", - "description": "ID of pet to fetch", + "description": "ID of pet that needs to be fetched", "required": true, "type": "integer", + "maximum": 10, + "minimum": 1, "format": "int64" } ], "responses": { "200": { - "description": "pet response", + "description": "successful operation", "schema": { - "$ref": "#/definitions/Pet" + "$ref": "#/definitions/Order" } }, + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Order not found" + } + } + }, + "delete": { + "tags": [ + "store" + ], + "summary": "Delete purchase order by ID", + "description": "For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors", + "operationId": "deleteOrder", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "orderId", + "in": "path", + "description": "ID of the order that needs to be deleted", + "required": true, + "type": "integer", + "minimum": 1, + "format": "int64" + } + ], + "responses": { + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Order not found" + } + } + } + }, + "/store/inventory": { + "get": { + "tags": [ + "store" + ], + "summary": "Returns pet inventories by status", + "description": "Returns a map of status codes to quantities", + "operationId": "getInventory", + "produces": [ + "application/json" + ], + "parameters": [], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "object", + "additionalProperties": { + "type": "integer", + "format": "int32" + } + } + } + }, + "security": [ + { + "api_key": [] + } + ] + } + }, + "/user/createWithArray": { + "post": { + "tags": [ + "user" + ], + "summary": "Creates list of users with given input array", + "description": "", + "operationId": "createUsersWithArrayInput", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "List of user object", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/User" + } + } + } + ], + "responses": { + "default": { + "description": "successful operation" + } + } + } + }, + "/user/createWithList": { + "post": { + "tags": [ + "user" + ], + "summary": "Creates list of users with given input array", + "description": "", + "operationId": "createUsersWithListInput", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "List of user object", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/User" + } + } + } + ], + "responses": { "default": { - "description": "unexpected error", + "description": "successful operation" + } + } + } + }, + "/user/{username}": { + "get": { + "tags": [ + "user" + ], + "summary": "Get user by user name", + "description": "", + "operationId": "getUserByName", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "username", + "in": "path", + "description": "The name that needs to be fetched. Use user1 for testing. ", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/User" + } + }, + "400": { + "description": "Invalid username supplied" + }, + "404": { + "description": "User not found" + } + } + }, + "put": { + "tags": [ + "user" + ], + "summary": "Updated user", + "description": "This can only be done by the logged in user.", + "operationId": "updateUser", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "username", + "in": "path", + "description": "name that need to be updated", + "required": true, + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "Updated user object", + "required": true, "schema": { - "$ref": "#/definitions/ErrorModel" + "$ref": "#/definitions/User" } } + ], + "responses": { + "400": { + "description": "Invalid user supplied" + }, + "404": { + "description": "User not found" + } } }, "delete": { - "description": "deletes a single pet based on the ID supplied", - "operationId": "deletePet", + "tags": [ + "user" + ], + "summary": "Delete user", + "description": "This can only be done by the logged in user.", + "operationId": "deleteUser", + "produces": [ + "application/json", + "application/xml" + ], "parameters": [ { - "name": "id", + "name": "username", "in": "path", - "description": "ID of pet to delete", + "description": "The name that needs to be deleted", "required": true, - "type": "integer", - "format": "int64" + "type": "string" } ], "responses": { - "204": { - "description": "pet deleted" + "400": { + "description": "Invalid username supplied" + }, + "404": { + "description": "User not found" + } + } + } + }, + "/user/login": { + "get": { + "tags": [ + "user" + ], + "summary": "Logs user into the system", + "description": "", + "operationId": "loginUser", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "username", + "in": "query", + "description": "The user name for login", + "required": true, + "type": "string" }, + { + "name": "password", + "in": "query", + "description": "The password for login in clear text", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "successful operation", + "headers": { + "X-Expires-After": { + "type": "string", + "format": "date-time", + "description": "date in UTC when token expires" + }, + "X-Rate-Limit": { + "type": "integer", + "format": "int32", + "description": "calls per hour allowed by the user" + } + }, + "schema": { + "type": "string" + } + }, + "400": { + "description": "Invalid username/password supplied" + } + } + } + }, + "/user/logout": { + "get": { + "tags": [ + "user" + ], + "summary": "Logs out current logged in user session", + "description": "", + "operationId": "logoutUser", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [], + "responses": { "default": { - "description": "unexpected error", + "description": "successful operation" + } + } + } + }, + "/user": { + "post": { + "tags": [ + "user" + ], + "summary": "Create user", + "description": "This can only be done by the logged in user.", + "operationId": "createUser", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "Created user object", + "required": true, "schema": { - "$ref": "#/definitions/ErrorModel" + "$ref": "#/definitions/User" } } + ], + "responses": { + "default": { + "description": "successful operation" + } } } } }, + "securityDefinitions": { + "api_key": { + "type": "apiKey", + "name": "api_key", + "in": "header" + }, + "petstore_auth": { + "type": "oauth2", + "authorizationUrl": "https://petstore.swagger.io/oauth/authorize", + "flow": "implicit", + "scopes": { + "read:pets": "read your pets", + "write:pets": "modify pets in your account" + } + } + }, "definitions": { - "Pet": { + "ApiResponse": { "type": "object", - "allOf": [ - { - "$ref": "#/definitions/NewPet" + "properties": { + "code": { + "type": "integer", + "format": "int32" }, - { - "required": [ - "id" - ], - "properties": { - "id": { - "type": "integer", - "format": "int64" - } - } + "type": { + "type": "string" + }, + "message": { + "type": "string" } - ] + } }, - "NewPet": { + "Category": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + } + }, + "xml": { + "name": "Category" + } + }, + "Pet": { "type": "object", "required": [ - "name" + "name", + "photoUrls" ], "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "category": { + "$ref": "#/definitions/Category" + }, "name": { - "type": "string" + "type": "string", + "example": "doggie" + }, + "photoUrls": { + "type": "array", + "xml": { + "wrapped": true + }, + "items": { + "type": "string", + "xml": { + "name": "photoUrl" + } + } + }, + "tags": { + "type": "array", + "xml": { + "wrapped": true + }, + "items": { + "xml": { + "name": "tag" + }, + "$ref": "#/definitions/Tag" + } }, - "tag": { + "status": { + "type": "string", + "description": "pet status in the store", + "enum": [ + "available", + "pending", + "sold" + ] + } + }, + "xml": { + "name": "Pet" + } + }, + "Tag": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { "type": "string" } + }, + "xml": { + "name": "Tag" } }, - "ErrorModel": { + "Order": { "type": "object", - "required": [ - "code", - "message" - ], "properties": { - "code": { + "id": { + "type": "integer", + "format": "int64" + }, + "petId": { + "type": "integer", + "format": "int64" + }, + "quantity": { "type": "integer", "format": "int32" }, - "message": { + "shipDate": { + "type": "string", + "format": "date-time" + }, + "status": { + "type": "string", + "description": "Order Status", + "enum": [ + "placed", + "approved", + "delivered" + ] + }, + "complete": { + "type": "boolean" + } + }, + "xml": { + "name": "Order" + } + }, + "User": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "username": { "type": "string" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "email": { + "type": "string" + }, + "password": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "userStatus": { + "type": "integer", + "format": "int32", + "description": "User Status" } + }, + "xml": { + "name": "User" } } + }, + "externalDocs": { + "description": "Find out more about Swagger", + "url": "http://swagger.io" } -} +} \ No newline at end of file From d695d900ad7859a8b29d8a0e65ac9b026480496f Mon Sep 17 00:00:00 2001 From: Martin Look Date: Thu, 4 Feb 2021 19:48:14 +0100 Subject: [PATCH 16/76] Fix routing base path. If the path is not stripped from the route the original base path has to be added to the routing base path. --- pkg/gateway/client.go | 13 +++++++++---- pkg/gateway/openapi.go | 4 ++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 38b47d6..0850254 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -147,8 +147,6 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se subscriptionInfo := gc.subscriptionManager.GetSubscriptionInfo(ep) - endpoints := gc.processKongRoute(proxyEndpoint, route, httpPort, httpsPort) - kongServiceSpec, err := specmanager.GetSpecification(ctx, service) if err != nil { // TODO: If no spec is found, then it was likely deleted, and should be deleted from central @@ -159,6 +157,8 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se spec: kongServiceSpec.Contents, } + endpoints := gc.processKongRoute(proxyEndpoint, oasSpec.BasePath(), route, httpPort, httpsPort) + serviceBody, err := gc.processKongAPI(*route.ID, service, oasSpec, endpoints, subscriptionInfo) if err != nil { return err @@ -194,7 +194,7 @@ func (gc *Client) deleteCentralService(serviceID string, serviceName string) { } } -func (gc *Client) processKongRoute(defaultHost string, route *klib.Route, httpPort, httpsPort int) []InstanceEndpoint { +func (gc *Client) processKongRoute(defaultHost string, basePath string, route *klib.Route, httpPort, httpsPort int) []InstanceEndpoint { var endpoints []InstanceEndpoint if route == nil { return endpoints @@ -210,11 +210,16 @@ func (gc *Client) processKongRoute(defaultHost string, route *klib.Route, httpPo if *protocol == "https" { port = httpsPort } + + routingBasePath := *path + if *route.StripPath == true { + routingBasePath = routingBasePath + basePath + } endpoint := InstanceEndpoint{ Host: *host, Port: int32(port), Protocol: *protocol, - Routing: v1alpha1.ApiServiceInstanceSpecRouting{BasePath: *path}, + Routing: v1alpha1.ApiServiceInstanceSpecRouting{BasePath: routingBasePath}, } endpoints = append(endpoints, endpoint) } diff --git a/pkg/gateway/openapi.go b/pkg/gateway/openapi.go index 2a1df8f..38273b2 100644 --- a/pkg/gateway/openapi.go +++ b/pkg/gateway/openapi.go @@ -30,3 +30,7 @@ func (oas *Openapi) Description() string { func (oas *Openapi) Version() string { return gjson.Get(oas.spec, "info.version").Str } + +func (oas *Openapi) BasePath() string { + return gjson.Get(oas.spec, "basePath").Str +} From 9d86af9b4c64b059ac9cb4b834eb28b0b635fcdd Mon Sep 17 00:00:00 2001 From: Victor Buciuc Date: Thu, 4 Feb 2021 12:01:36 -0700 Subject: [PATCH 17/76] install unsubscribe handler --- pkg/gateway/client.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 0850254..903bcef 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -335,6 +335,7 @@ func initSubscriptionManager(kc *klib.Client) (*subscription.Manager, error) { agent.GetCentralClient().GetSubscriptionManager().RegisterValidator(sm.ValidateSubscription) // register validator and handlers agent.GetCentralClient().GetSubscriptionManager().RegisterProcessor(apic.SubscriptionApproved, sm.ProcessSubscribe) + agent.GetCentralClient().GetSubscriptionManager().RegisterProcessor(apic.SubscriptionUnsubscribeInitiated, sm.ProcessUnsubscribe) // start polling for subscriptions agent.GetCentralClient().GetSubscriptionManager().Start() From e51d5114a7927ad466f5eb982ec5b9797061f31d Mon Sep 17 00:00:00 2001 From: Sagar Date: Thu, 4 Feb 2021 15:27:08 -0700 Subject: [PATCH 18/76] Add application ID and name --- default_kong_traceability_agent.yml | 6 ++++ ...tom_log_filebeater.go => custom_beater.go} | 36 ++++++++++--------- pkg/cmd/traceability/traceabilityCmd.go | 16 ++++++++- pkg/config/traceability/config.go | 20 +++++++++-- pkg/processor/definitions.go | 17 ++++----- pkg/processor/eventmapper.go | 14 +++++--- 6 files changed, 77 insertions(+), 32 deletions(-) rename pkg/beater/{custom_log_filebeater.go => custom_beater.go} (67%) diff --git a/default_kong_traceability_agent.yml b/default_kong_traceability_agent.yml index 6947e0e..0393af8 100644 --- a/default_kong_traceability_agent.yml +++ b/default_kong_traceability_agent.yml @@ -15,6 +15,12 @@ central: timeout: 20s url: https://login.axway.com/auth +http_log_plugin_config: + # Path used by Kong's HTTP Log plugin to send request logs + path: ${LOGS_HTTP_SERVER_PATH} + # Port that listens for request logs sent by Kong's HTTP Log plugin + port: ${LOGS_HTTP_SERVER_PORT} + # Condor Ingestion service output.traceability: compression_level: ${TRACEABILITY_COMPRESSIONLEVEL:3} diff --git a/pkg/beater/custom_log_filebeater.go b/pkg/beater/custom_beater.go similarity index 67% rename from pkg/beater/custom_log_filebeater.go rename to pkg/beater/custom_beater.go index be6a9ca..11e1af8 100644 --- a/pkg/beater/custom_log_filebeater.go +++ b/pkg/beater/custom_beater.go @@ -6,6 +6,8 @@ import ( "log" "net/http" + traceabilityconfig "github.com/Axway/agents-kong/pkg/config/traceability" + "github.com/Axway/agents-kong/pkg/processor" agentErrors "github.com/Axway/agent-sdk/pkg/util/errors" @@ -49,30 +51,32 @@ func (bt *customLogBeater) Run(b *beat.Beat) error { return err } - http.HandleFunc("/requestlogs", func(w http.ResponseWriter, r *http.Request) { - if r.Method != http.MethodPost { - w.WriteHeader(http.StatusMethodNotAllowed) - return - } + http.HandleFunc(fmt.Sprintf("%s", traceabilityconfig.GetAgentConfig().HttpLogPluginConfig.Path), + func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } - body, err := ioutil.ReadAll(r.Body) - defer r.Body.Close() + body, err := ioutil.ReadAll(r.Body) + defer r.Body.Close() - if err != nil { - fmt.Errorf("Error while reading request body: %s", err) - } + if err != nil { + fmt.Errorf("Error while reading request body: %s", err) + } - w.WriteHeader(200) - bt.processAndDispatchEvent(string(body)) - }) + w.WriteHeader(200) + bt.processAndDispatchEvent(string(body)) + }) /* Start a new HTTP server in a separate Go routine that will be the target for the HTTP Log plugin. It should write events it gets to eventChannel */ go func() { - if err := http.ListenAndServe(":9000", nil); err != nil { - log.Fatalf("Unable to start the HTTP Server: %s", err) + if err := http.ListenAndServe(fmt.Sprintf(":%d", traceabilityconfig.GetAgentConfig().HttpLogPluginConfig.Port), + nil); err != nil { + log.Fatal("Unable to start the HTTP Server: %s", err) } - log.Print("Started HTTP server on port 9000 to receive request logs") + fmt.Printf("Started HTTP server on port %d to receive request logs", traceabilityconfig.GetAgentConfig().HttpLogPluginConfig.Port) }() for { diff --git a/pkg/cmd/traceability/traceabilityCmd.go b/pkg/cmd/traceability/traceabilityCmd.go index 03ba756..0ca8e64 100644 --- a/pkg/cmd/traceability/traceabilityCmd.go +++ b/pkg/cmd/traceability/traceabilityCmd.go @@ -31,6 +31,10 @@ func init() { run, corecfg.TraceabilityAgent, ) + + rootProps := TraceCmd.GetProperties() + rootProps.AddStringProperty("http_log_plugin_config.path", "/requestlogs", "Path on which the HTTP Log plugin sends request logs") + rootProps.AddIntProperty("http_log_plugin_config.port", 9000, "Port that listens for request logs from HTTP Log plugin") } func run() error { @@ -41,9 +45,19 @@ func run() error { // and passed to the callback allowing the agent code to access the central config func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { + rootProps := TraceCmd.GetProperties() + + httpLogPluginConfig := &config.HttpLogPluginConfig{ + Port: rootProps.IntPropertyValue("http_log_plugin_config.port"), + Path: rootProps.StringPropertyValue("http_log_plugin_config.path"), + } + agentConfig := &config.AgentConfig{ - CentralCfg: centralConfig, + CentralCfg: centralConfig, + HttpLogPluginConfig: httpLogPluginConfig, } + config.SetAgentConfig(agentConfig) + return agentConfig, nil } diff --git a/pkg/config/traceability/config.go b/pkg/config/traceability/config.go index 778db50..edf1564 100644 --- a/pkg/config/traceability/config.go +++ b/pkg/config/traceability/config.go @@ -1,4 +1,4 @@ -package traceability +package traceabilityconfig import ( corecfg "github.com/Axway/agent-sdk/pkg/config" @@ -6,5 +6,21 @@ import ( // AgentConfig - represents the config for agent type AgentConfig struct { - CentralCfg corecfg.CentralConfig `config:"central"` + CentralCfg corecfg.CentralConfig `config:"central"` + HttpLogPluginConfig *HttpLogPluginConfig `config:"http_log_plugin_config"` +} + +type HttpLogPluginConfig struct { + Path string `config:"path"` + Port int `config:"port"` +} + +var agentConfig *AgentConfig + +func SetAgentConfig(cfg *AgentConfig) { + agentConfig = cfg +} + +func GetAgentConfig() *AgentConfig { + return agentConfig } diff --git a/pkg/processor/definitions.go b/pkg/processor/definitions.go index 122add2..fd102f6 100644 --- a/pkg/processor/definitions.go +++ b/pkg/processor/definitions.go @@ -10,7 +10,7 @@ type KongTrafficLogEntry struct { Response *Response `json:"response"` Route *Route `json:"route"` Service *Service `json:"service"` - Tries []*Tries `json:"tries"` + Consumer *Consumer `json:"consumer"` } type Latencies struct { @@ -70,16 +70,17 @@ type Service struct { WsID string `json:"ws_id"` } -type Tries struct { - BalancerLatency int `json:"balancer_latency"` - Port int `json:"port"` - BalancerStart int64 `json:"balancer_start"` - IP string `json:"ip"` -} - type TLS struct { Version string `json:"version"` Cipher string `json:"cipher"` SupportedClientCiphers string `json:"supported_client_ciphers"` ClientVerify string `json:"client_verify"` } + +type Consumer struct { + CustomID string `json:"custom_id"` + CreatedAt string `json:"created_at"` + ID string `json:"id"` + Tags []string `json:"tags"` + Username string `json:"username"` +} diff --git a/pkg/processor/eventmapper.go b/pkg/processor/eventmapper.go index 09b3d2f..59f127a 100644 --- a/pkg/processor/eventmapper.go +++ b/pkg/processor/eventmapper.go @@ -117,8 +117,7 @@ func (m *EventMapper) createTransactionEvent(ktle KongTrafficLogEntry) (*transac SetHost(ktle.Request.Headers[host]). SetHeaders(m.buildHeaders(ktle.Request.Headers), m.buildHeaders(ktle.Response.Headers)). SetByteLength(ktle.Request.Size, ktle.Response.Size). - SetRemoteAddress("", "", ktle.Tries[0].Port). // No way to find remote address for now - SetLocalAddress(ktle.ClientIP, 0). // Could not determine local port for now + SetLocalAddress(ktle.ClientIP, 0). // Could not determine local port for now SetSSLProperties(m.buildSSLInfoIfAvailable(ktle)). SetUserAgent(ktle.Request.Headers[userAgent]). Build() @@ -144,7 +143,7 @@ func (m *EventMapper) createTransactionEvent(ktle KongTrafficLogEntry) (*transac func (m *EventMapper) createSummaryEvent(ktle KongTrafficLogEntry, teamID string) (*transaction.LogEvent, error) { - return transaction.NewTransactionSummaryBuilder(). + builder := transaction.NewTransactionSummaryBuilder(). SetTimestamp(ktle.StartedAt). SetTransactionID(m.trimRequestId(ktle.Request.Headers[requestID])). SetStatus(m.getTransactionSummaryStatus(ktle.Response.Status), @@ -157,6 +156,11 @@ func (m *EventMapper) createSummaryEvent(ktle KongTrafficLogEntry, teamID string SetDuration(ktle.Latencies.Request). SetProxy(transaction.FormatProxyID(ktle.Service.ID), ktle.Service.Name, - 1). - Build() + 1) + + if ktle.Consumer != nil { + builder.SetApplication(transaction.FormatApplicationID(ktle.Consumer.ID), ktle.Consumer.Username) + } + + return builder.Build() } From ebca01e4cb3dc95a45145d28a7213bc865f8a3f6 Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Thu, 4 Feb 2021 15:47:42 -0700 Subject: [PATCH 19/76] update (#6) --- README.md | 19 +++++++++++++++---- default_kong_discovery_agent.yml | 10 +++++----- go.mod | 3 +-- go.sum | 4 ++-- pkg/cmd/discovery/discoveryCmd.go | 20 ++++++++++---------- pkg/config/discovery/config.go | 8 ++++---- pkg/gateway/cache.go | 2 -- pkg/gateway/centralclient.go | 1 - pkg/gateway/client.go | 8 ++++---- 9 files changed, 41 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index ffccd22..ff8b466 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Copy the content of `default_kong_traceability_agent.yml` to a new file named `k In each of the two config files for the agents provide the following variables for your config. Provide the `environment`, `organizationID`, `platformURL`, `team`, `url`, `clientID`, `privateKey`, `publicKey` (provide the full file path to the keys). -In the `kong_discovery_agent.yml` file provide the details of the kong user. `admin_endpoint`, `user`, `token` +In the `kong_discovery_agent.yml` file provide the details of the kong user. `adminEndpoint`, `proxyEndpoint`, `proxyEndpointProtocols`, `user`, `token` # Run the agents @@ -52,8 +52,19 @@ In development you can run an agent by running `go run ./cmd/discovery/discovery ## Build and run the binary -To build the agents run `make build` +To build the discovery agent run `make build-disc` -To run the discovery agent run `make run-discovery` +To build the traceability agent run `make build-trace` -To run the traceability agent run `make run-traceability` \ No newline at end of file +To run the discovery agent run `make run-disc` + +To run the traceability agent run `make run-trace` + +# Kong Discovery Agent + +The discovery agent + +The discovery agent has two mode to discover specs. Specs can be discovered from either the Kong Developer Portal by setting `specDevPortalEnabled` to `true`, or they can be discovered from a local directory. +To discover specs from a local directory provide a file path for the agent to look find specs in by setting the `specHomePath` field. + +# Kong Traceability Agent \ No newline at end of file diff --git a/default_kong_discovery_agent.yml b/default_kong_discovery_agent.yml index 9d1151a..205cd61 100644 --- a/default_kong_discovery_agent.yml +++ b/default_kong_discovery_agent.yml @@ -22,12 +22,12 @@ log: path: logs kong: - admin_endpoint: + adminEndpoint: token: 1234 user: admin - proxy_endpoint: - proxy_endpoint_protocols: + proxyEndpoint: + proxyEndpointProtocols: http: 80 https: 443 - spec_dev_portal_enabled: - spec_home_path: + specDevPortalEnabled: + specHomePath: diff --git a/go.mod b/go.mod index f810451..4e4a0c6 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Axway/agents-kong go 1.13 require ( - github.com/Axway/agent-sdk v0.0.20-0.20210204011617-097b5510cacd + github.com/Axway/agent-sdk v0.0.20-0.20210204223503-cc5b7758ff13 github.com/Shopify/sarama v1.26.4 // indirect github.com/docker/docker v1.13.1 // indirect github.com/dustin/go-humanize v1.0.0 // indirect @@ -12,7 +12,6 @@ require ( github.com/garyburd/redigo v1.6.0 // indirect github.com/googleapis/gnostic v0.3.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hpcloud/tail v1.0.0 github.com/imdario/mergo v0.3.9 // indirect github.com/jcmturner/gofork v1.0.0 // indirect github.com/klauspost/cpuid v1.3.1 // indirect diff --git a/go.sum b/go.sum index 61aa0b5..518cdd1 100644 --- a/go.sum +++ b/go.sum @@ -19,8 +19,8 @@ code.cloudfoundry.org/go-loggregator v7.4.0+incompatible/go.mod h1:KPBTRqj+y738N code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:sk5LnIjB/nIEU7yP5sDQExVm62wu0pBh3yrElngUisI= code.cloudfoundry.org/rfc5424 v0.0.0-20180905210152-236a6d29298a/go.mod h1:tkZo8GtzBjySJ7USvxm4E36lNQw1D3xM6oKHGqdaAJ4= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Axway/agent-sdk v0.0.20-0.20210204011617-097b5510cacd h1:SaZIGyMcqhrOIAoLOiPRZDrwjSyLsIcJuMuvZQn6dbQ= -github.com/Axway/agent-sdk v0.0.20-0.20210204011617-097b5510cacd/go.mod h1:fOaWmFFg1eDheNJZNe2+T/jRwfSm8AWcap1p+ytBv8I= +github.com/Axway/agent-sdk v0.0.20-0.20210204223503-cc5b7758ff13 h1:J8SEyRi30hr0SzLLLbinaEVU1kMmU+9RVasdcBP/ZTU= +github.com/Axway/agent-sdk v0.0.20-0.20210204223503-cc5b7758ff13/go.mod h1:fOaWmFFg1eDheNJZNe2+T/jRwfSm8AWcap1p+ytBv8I= github.com/Azure/azure-amqp-common-go/v3 v3.0.0/go.mod h1:SY08giD/XbhTz07tJdpw1SoxQXHPN30+DI3Z04SYqyg= github.com/Azure/azure-event-hubs-go/v3 v3.1.2/go.mod h1:hR40byNJjKkS74+3RhloPQ8sJ8zFQeJ920Uk3oYY0+k= github.com/Azure/azure-pipeline-go v0.1.8/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg= diff --git a/pkg/cmd/discovery/discoveryCmd.go b/pkg/cmd/discovery/discoveryCmd.go index f07fa98..1db1256 100644 --- a/pkg/cmd/discovery/discoveryCmd.go +++ b/pkg/cmd/discovery/discoveryCmd.go @@ -28,10 +28,10 @@ func init() { rootProps := DiscoveryCmd.GetProperties() rootProps.AddStringProperty("kong.user", "", "Kong Gateway admin user") rootProps.AddStringProperty("kong.token", "", "Token to authenticate with Kong Gateway") - rootProps.AddStringProperty("kong.admin_endpoint", "", "The Kong admin endpoint") - rootProps.AddStringProperty("kong.proxy_endpoint", "", "The Kong proxy endpoint") - rootProps.AddIntProperty("kong.proxy_endpoint_protocols.http", 80, "The Kong proxy http port") - rootProps.AddIntProperty("kong.proxy_endpoint_protocols.https", 443, "The Kong proxy https port") + rootProps.AddStringProperty("kong.adminEndpoint", "", "The Kong admin endpoint") + rootProps.AddStringProperty("kong.proxyEndpoint", "", "The Kong proxy endpoint") + rootProps.AddIntProperty("kong.proxyEndpointProtocols.http", 80, "The Kong proxy http port") + rootProps.AddIntProperty("kong.proxyEndpointProtocols.https", 443, "The Kong proxy https port") } // Callback that agent will call to process the execution @@ -69,14 +69,14 @@ func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { // Parse the config from bound properties and setup gateway config gatewayConfig := &config.KongGatewayConfig{ - AdminEndpoint: rootProps.StringPropertyValue("kong.admin_endpoint"), + AdminEndpoint: rootProps.StringPropertyValue("kong.adminEndpoint"), Token: rootProps.StringPropertyValue("kong.token"), User: rootProps.StringPropertyValue("kong.user"), - ProxyEndpoint: rootProps.StringPropertyValue("kong.proxy_endpoint"), - ProxyHttpPort: rootProps.IntPropertyValue("kong.proxy_endpoint_protocols.http"), - ProxyHttpsPort: rootProps.IntPropertyValue("kong.proxy_endpoint_protocols.https"), - SpecHomePath: rootProps.StringPropertyValue("kong.spec_home_path"), - SpecDevPortalEnabled: rootProps.BoolPropertyValue("kong.spec_dev_portal_enabled"), + ProxyEndpoint: rootProps.StringPropertyValue("kong.proxyEndpoint"), + ProxyHttpPort: rootProps.IntPropertyValue("kong.proxyEndpointProtocols.http"), + ProxyHttpsPort: rootProps.IntPropertyValue("kong.proxyEndpointProtocols.https"), + SpecHomePath: rootProps.StringPropertyValue("kong.specHomePath"), + SpecDevPortalEnabled: rootProps.BoolPropertyValue("kong.specDevPortalEnabled"), } agentConfig = config.AgentConfig{ diff --git a/pkg/config/discovery/config.go b/pkg/config/discovery/config.go index de87745..a64aead 100644 --- a/pkg/config/discovery/config.go +++ b/pkg/config/discovery/config.go @@ -31,13 +31,13 @@ func (c *KongGatewayConfig) ValidateCfg() (err error) { return fmt.Errorf("error: token is required") } if c.AdminEndpoint == "" { - return fmt.Errorf("error: admin_endpoint is required") + return fmt.Errorf("error: adminEndpoint is required") } if c.ProxyEndpoint == "" { - return fmt.Errorf("error: proxy_endpoint is required") + return fmt.Errorf("error: proxyEndpoint is required") } - if c.ProxyHttpPort == 0 || c.ProxyHttpsPort == 0 { - return fmt.Errorf("error: proxy_endpoint_protocols requires at least one value of either http or https") + if c.ProxyHttpPort == 0 && c.ProxyHttpsPort == 0 { + return fmt.Errorf("error: proxyEndpointProtocols requires at least one value of either http or https") } if c.User == "" { return fmt.Errorf("error: user is required") diff --git a/pkg/gateway/cache.go b/pkg/gateway/cache.go index d5385c7..f2a40c0 100644 --- a/pkg/gateway/cache.go +++ b/pkg/gateway/cache.go @@ -42,14 +42,12 @@ func setCachedService(kongServiceId string, kongServiceName string, hash string, func initCache(centralAPIServices []*v1alpha1.APIService) { clearCache() - log.Info("Init the cache") for _, apiSvc := range centralAPIServices { setCachedService(apiSvc.Attributes[kongServiceID], apiSvc.Title, apiSvc.Attributes[kongHash], apiSvc.Name) } } func clearCache() { - log.Info("Cache cleared") cache := cache.GetCache() for _, key := range cache.GetKeys() { cache.Delete(key) diff --git a/pkg/gateway/centralclient.go b/pkg/gateway/centralclient.go index 2de31cb..d5f05a7 100644 --- a/pkg/gateway/centralclient.go +++ b/pkg/gateway/centralclient.go @@ -30,7 +30,6 @@ func NewCentralClient(client CentralAPIClient, config corecfg.CentralConfig) Cen func (cc *CentralClient) execute(method, endpoint string, queryParam map[string]string, buffer []byte) ([]byte, error) { host := cc.apiServerHost + cc.envName + endpoint - log.Infof("sending %s request: %s", method, host) return cc.client.ExecuteAPI(method, host, queryParam, buffer) } diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 903bcef..24c7f89 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -149,7 +149,6 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se kongServiceSpec, err := specmanager.GetSpecification(ctx, service) if err != nil { - // TODO: If no spec is found, then it was likely deleted, and should be deleted from central return fmt.Errorf("failed to get spec for %s: %s", *service.Name, err) } @@ -164,7 +163,8 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se return err } if serviceBody == nil { - return fmt.Errorf("not processing '%s' since no changes were detected", *service.Name) + log.Debugf("not processing '%s' since no changes were detected", *service.Name) + return nil } err = agent.PublishAPI(*serviceBody) @@ -172,13 +172,13 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se return fmt.Errorf("failed to publish api: %s", err) } - log.Info("Published API " + serviceBody.APIName + " to AMPLIFY Central") + log.Infof("Published API '%s' to central", serviceBody.APIName) return nil } func (gc *Client) deleteCentralService(serviceID string, serviceName string) { - log.Warnf("kong service '%s' has no routes. Attempting to delete the service from central", serviceName) + log.Debugf("kong service '%s' has no routes.", serviceName) item, _ := cache.GetCache().Get(serviceID) if svc, ok := item.(CachedService); ok { From 35076a0311ce0e31117ddcbacc944389efb570fe Mon Sep 17 00:00:00 2001 From: Sagar Date: Thu, 4 Feb 2021 16:14:22 -0700 Subject: [PATCH 20/76] Fix Consumer JSON unmarshall --- pkg/processor/definitions.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/processor/definitions.go b/pkg/processor/definitions.go index fd102f6..21604b1 100644 --- a/pkg/processor/definitions.go +++ b/pkg/processor/definitions.go @@ -37,10 +37,10 @@ type Response struct { type Route struct { ID string `json:"id"` - UpdatedAt int `json:"updated_at"` + UpdatedAt int64 `json:"updated_at"` Protocols []string `json:"protocols"` StripPath bool `json:"strip_path"` - CreatedAt int `json:"created_at"` + CreatedAt int64 `json:"created_at"` WsID string `json:"ws_id"` Service map[string]string `json:"service"` Name string `json:"name"` @@ -56,7 +56,7 @@ type Route struct { type Service struct { Host string `json:"host"` - CreatedAt int `json:"created_at"` + CreatedAt int64 `json:"created_at"` ConnectTimeout int `json:"connect_timeout"` ID string `json:"id"` Protocol string `json:"protocol"` @@ -64,7 +64,7 @@ type Service struct { ReadTimeout int `json:"read_timeout"` Port int `json:"port"` Path string `json:"path"` - UpdatedAt int `json:"updated_at"` + UpdatedAt int64 `json:"updated_at"` WriteTimeout int `json:"write_timeout"` Retries int `json:"retries"` WsID string `json:"ws_id"` @@ -79,7 +79,7 @@ type TLS struct { type Consumer struct { CustomID string `json:"custom_id"` - CreatedAt string `json:"created_at"` + CreatedAt int64 `json:"created_at"` ID string `json:"id"` Tags []string `json:"tags"` Username string `json:"username"` From 3cb5fd588844710af5afe7d19dea0902961ee085 Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Thu, 4 Feb 2021 16:25:28 -0700 Subject: [PATCH 21/76] Make kong token config value optional (#7) --- default_kong_discovery_agent.yml | 1 - pkg/cmd/discovery/discoveryCmd.go | 2 -- pkg/config/discovery/config.go | 9 +++------ pkg/kong/kongclient.go | 22 +++++++++++++--------- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/default_kong_discovery_agent.yml b/default_kong_discovery_agent.yml index 205cd61..d1f28ce 100644 --- a/default_kong_discovery_agent.yml +++ b/default_kong_discovery_agent.yml @@ -24,7 +24,6 @@ log: kong: adminEndpoint: token: 1234 - user: admin proxyEndpoint: proxyEndpointProtocols: http: 80 diff --git a/pkg/cmd/discovery/discoveryCmd.go b/pkg/cmd/discovery/discoveryCmd.go index 1db1256..8e75fec 100644 --- a/pkg/cmd/discovery/discoveryCmd.go +++ b/pkg/cmd/discovery/discoveryCmd.go @@ -26,7 +26,6 @@ func init() { // Get the root command properties and bind the config property in YAML definition rootProps := DiscoveryCmd.GetProperties() - rootProps.AddStringProperty("kong.user", "", "Kong Gateway admin user") rootProps.AddStringProperty("kong.token", "", "Token to authenticate with Kong Gateway") rootProps.AddStringProperty("kong.adminEndpoint", "", "The Kong admin endpoint") rootProps.AddStringProperty("kong.proxyEndpoint", "", "The Kong proxy endpoint") @@ -71,7 +70,6 @@ func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { gatewayConfig := &config.KongGatewayConfig{ AdminEndpoint: rootProps.StringPropertyValue("kong.adminEndpoint"), Token: rootProps.StringPropertyValue("kong.token"), - User: rootProps.StringPropertyValue("kong.user"), ProxyEndpoint: rootProps.StringPropertyValue("kong.proxyEndpoint"), ProxyHttpPort: rootProps.IntPropertyValue("kong.proxyEndpointProtocols.http"), ProxyHttpsPort: rootProps.IntPropertyValue("kong.proxyEndpointProtocols.https"), diff --git a/pkg/config/discovery/config.go b/pkg/config/discovery/config.go index a64aead..f6b112f 100644 --- a/pkg/config/discovery/config.go +++ b/pkg/config/discovery/config.go @@ -4,6 +4,7 @@ import ( "fmt" corecfg "github.com/Axway/agent-sdk/pkg/config" + "github.com/Axway/agent-sdk/pkg/util/log" ) // AgentConfig - represents the config for agent @@ -17,7 +18,6 @@ type KongGatewayConfig struct { corecfg.IConfigValidator AdminEndpoint string `config:"adminEndpoint"` Token string `config:"token"` - User string `config:"user"` ProxyEndpoint string `config:"proxyEndpoint"` ProxyHttpPort int `config:"proxyHttpPort"` ProxyHttpsPort int `config:"proxyHttpsPort"` @@ -27,9 +27,6 @@ type KongGatewayConfig struct { // ValidateCfg - Validates the gateway config func (c *KongGatewayConfig) ValidateCfg() (err error) { - if c.Token == "" { - return fmt.Errorf("error: token is required") - } if c.AdminEndpoint == "" { return fmt.Errorf("error: adminEndpoint is required") } @@ -39,8 +36,8 @@ func (c *KongGatewayConfig) ValidateCfg() (err error) { if c.ProxyHttpPort == 0 && c.ProxyHttpsPort == 0 { return fmt.Errorf("error: proxyEndpointProtocols requires at least one value of either http or https") } - if c.User == "" { - return fmt.Errorf("error: user is required") + if c.Token == "" { + log.Warn("no token set for authenticating with the kong admin endpoint") } return } diff --git a/pkg/kong/kongclient.go b/pkg/kong/kongclient.go index 054a17f..51ac33d 100644 --- a/pkg/kong/kongclient.go +++ b/pkg/kong/kongclient.go @@ -4,10 +4,11 @@ import ( "context" "encoding/json" "fmt" - "github.com/Axway/agents-kong/pkg/kong/specmanager" "io/ioutil" "net/http" + "github.com/Axway/agents-kong/pkg/kong/specmanager" + config "github.com/Axway/agents-kong/pkg/config/discovery" klib "github.com/kong/go-kong/kong" @@ -27,20 +28,23 @@ type KongClient struct { } func NewKongClient(baseClient *http.Client, kongConfig *config.KongGatewayConfig) (*KongClient, error) { - defaultTransport := http.DefaultTransport.(*http.Transport) - baseClient.Transport = defaultTransport - - headers := make(http.Header) - headers.Set("Kong-Admin-Token", kongConfig.Token) - client := klib.HTTPClientWithHeaders(baseClient, headers) + if kongConfig.Token != "" { + defaultTransport := http.DefaultTransport.(*http.Transport) + baseClient.Transport = defaultTransport + + headers := make(http.Header) + headers.Set("Kong-Admin-Token", kongConfig.Token) + client := klib.HTTPClientWithHeaders(baseClient, headers) + baseClient = &client + } - baseKongClient, err := klib.NewClient(&kongConfig.AdminEndpoint, &client) + baseKongClient, err := klib.NewClient(&kongConfig.AdminEndpoint, baseClient) if err != nil { return nil, err } return &KongClient{ Client: baseKongClient, - baseClient: &client, + baseClient: baseClient, kongAdminEndpoint: kongConfig.AdminEndpoint, }, nil } From c388b420b2076cbcdaa40166b25a3f25ca4309dc Mon Sep 17 00:00:00 2001 From: Sagar Date: Thu, 4 Feb 2021 16:45:25 -0700 Subject: [PATCH 22/76] Use uuid generator for txn ID --- go.mod | 1 + go.sum | 2 ++ pkg/processor/eventmapper.go | 26 ++++++++++---------------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/go.mod b/go.mod index 4e4a0c6..7cf0a72 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/eapache/go-resiliency v1.2.0 // indirect github.com/elastic/beats/v7 v7.7.1 github.com/garyburd/redigo v1.6.0 // indirect + github.com/google/uuid v1.2.0 github.com/googleapis/gnostic v0.3.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/imdario/mergo v0.3.9 // indirect diff --git a/go.sum b/go.sum index 518cdd1..b5a1882 100644 --- a/go.sum +++ b/go.sum @@ -301,6 +301,8 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.2-0.20190416172445-c2e93f3ae59f/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= diff --git a/pkg/processor/eventmapper.go b/pkg/processor/eventmapper.go index 59f127a..8fcedf7 100644 --- a/pkg/processor/eventmapper.go +++ b/pkg/processor/eventmapper.go @@ -6,7 +6,8 @@ import ( "fmt" "net/http" "strconv" - "strings" + + "github.com/google/uuid" "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/transaction" @@ -17,14 +18,14 @@ import ( type EventMapper struct { } -const requestID = "kong-request-id" const host = "host" const userAgent = "user-agent" -const hash = "#" func (m *EventMapper) processMapping(kongTrafficLogEntry KongTrafficLogEntry) ([]*transaction.LogEvent, error) { centralCfg := agent.GetCentralConfig() - transactionLegEvent, err := m.createTransactionEvent(kongTrafficLogEntry) + txnID := uuid.New().String() + + transactionLegEvent, err := m.createTransactionEvent(kongTrafficLogEntry, txnID) if err != nil { log.Errorf("Error while building transaction leg event: %s", err) return nil, err @@ -37,7 +38,7 @@ func (m *EventMapper) processMapping(kongTrafficLogEntry KongTrafficLogEntry) ([ log.Debug("Generated Transaction leg event: ", string(jTransactionLegEvent)) - transSummaryLogEvent, err := m.createSummaryEvent(kongTrafficLogEntry, centralCfg.GetTeamID()) + transSummaryLogEvent, err := m.createSummaryEvent(kongTrafficLogEntry, centralCfg.GetTeamID(), txnID) if err != nil { log.Errorf("Error while building transaction summary event: %s", err) return nil, err @@ -100,14 +101,7 @@ func (m *EventMapper) processQueryArgs(args map[string]string) string { return b.String() } -func (m *EventMapper) trimRequestId(reqId string) string { - if strings.Contains(reqId, hash) { - return strings.Split(reqId, hash)[0] - } - return reqId -} - -func (m *EventMapper) createTransactionEvent(ktle KongTrafficLogEntry) (*transaction.LogEvent, error) { +func (m *EventMapper) createTransactionEvent(ktle KongTrafficLogEntry, txnid string) (*transaction.LogEvent, error) { httpProtocolDetails, err := transaction.NewHTTPProtocolBuilder(). SetURI(ktle.Request.URI). @@ -129,7 +123,7 @@ func (m *EventMapper) createTransactionEvent(ktle KongTrafficLogEntry) (*transac return transaction.NewTransactionEventBuilder(). SetTimestamp(ktle.StartedAt). - SetTransactionID(m.trimRequestId(ktle.Request.Headers[requestID])). + SetTransactionID(txnid). SetID("leg0"). SetParentID(""). SetSource("client_ip"). @@ -141,11 +135,11 @@ func (m *EventMapper) createTransactionEvent(ktle KongTrafficLogEntry) (*transac Build() } -func (m *EventMapper) createSummaryEvent(ktle KongTrafficLogEntry, teamID string) (*transaction.LogEvent, error) { +func (m *EventMapper) createSummaryEvent(ktle KongTrafficLogEntry, teamID string, txnid string) (*transaction.LogEvent, error) { builder := transaction.NewTransactionSummaryBuilder(). SetTimestamp(ktle.StartedAt). - SetTransactionID(m.trimRequestId(ktle.Request.Headers[requestID])). + SetTransactionID(txnid). SetStatus(m.getTransactionSummaryStatus(ktle.Response.Status), strconv.Itoa(ktle.Response.Status)). SetTeam(teamID). From da3f862c15f9374cc319753a0da35be69427a324 Mon Sep 17 00:00:00 2001 From: Sagar Date: Thu, 4 Feb 2021 17:15:14 -0700 Subject: [PATCH 23/76] Update README --- README.md | 37 ++++++++++++++++++++++++------------- Traceability-README.md | 31 ------------------------------- 2 files changed, 24 insertions(+), 44 deletions(-) delete mode 100644 Traceability-README.md diff --git a/README.md b/README.md index ff8b466..8ddd31f 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,10 @@ Provide a name and a title, such as "kong-gateway" and then hit "Save" in the to ## Create a DOSA Account Create a public and private key pair locally on your computer. +```shell +openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048 +openssl rsa -in private_key.pem -pubout -out public_key.pem +``` In Central, click the "Access" tab on the sidebar, which is the second to last tab. Click on "Service Accounts". Click the button in the top right that says "+ Service Account". @@ -42,29 +46,36 @@ Provide the `environment`, `organizationID`, `platformURL`, `team`, `url`, `clie In the `kong_discovery_agent.yml` file provide the details of the kong user. `adminEndpoint`, `proxyEndpoint`, `proxyEndpointProtocols`, `user`, `token` -# Run the agents +In the `kong_traceability_agent.yml` overrides can be provided if desired under `http_log_plugin_config` for the path and port for http endpoint that listens for request logs from Kong's HTTP Log plugin -## Development - -Each agent is built and run independently +# Kong Discovery Agent -In development you can run an agent by running `go run ./cmd/discovery/discovery.go` or `go run ./cmd/discovery/traceability.go`. You do not need to build the binary for agents on every change. +The discovery agent has two modes to discover specs. Specs can be discovered from either the Kong Developer Portal by setting `specDevPortalEnabled` to `true`, or they can be discovered from a local directory. +To discover specs from a local directory provide a file path for the agent to look find specs in by setting the `specHomePath` field. ## Build and run the binary To build the discovery agent run `make build-disc` -To build the traceability agent run `make build-trace` - To run the discovery agent run `make run-disc` -To run the traceability agent run `make run-trace` +# Kong Traceability Agent -# Kong Discovery Agent +Kong Traceability agent does these tasks: +* Runs an HTTP Server exposing an endpoint that serves as the target for Kong's [HTTP Log Plugin](https://docs.konghq.com/hub/kong-inc/http-log/) +* Processes the request logs as they are sent by the HTTP Log plugin and builds transaction summary and transaction leg event in the format expected by Central's API Observer +* Uses libbeat to publish the events to Condor -The discovery agent +## Prerequisites +Kong Traceability agent requires **global deployment** of the below plugin on your Kong instance in order to generate transaction summary and transaction leg event for all Kong's proxies +* [HTTP Log Plugin](https://docs.konghq.com/hub/kong-inc/http-log/) used to get the request logs associated with Kong proxy invocation -The discovery agent has two mode to discover specs. Specs can be discovered from either the Kong Developer Portal by setting `specDevPortalEnabled` to `true`, or they can be discovered from a local directory. -To discover specs from a local directory provide a file path for the agent to look find specs in by setting the `specHomePath` field. +## Build and run the binary + +To build the traceability agent run `make build-trace` + +To run the traceability agent run `make run-trace` + +# Development -# Kong Traceability Agent \ No newline at end of file +In development you can run an agent by running `go run ./cmd/discovery/main.go` or `go run ./cmd/traceability/main.go`. You do not need to build the binary for agents on every change. \ No newline at end of file diff --git a/Traceability-README.md b/Traceability-README.md deleted file mode 100644 index 3a6eb33..0000000 --- a/Traceability-README.md +++ /dev/null @@ -1,31 +0,0 @@ -# Kong Traceability agent - -## Overview -Kong Traceability agent does these tasks: -* Runs an HTTP Server exposing an endpoint that serves as the target for Kong's [HTTP Log Plugin](https://docs.konghq.com/hub/kong-inc/http-log/) -* Processes the request logs as they are sent by the HTTP Log plugin and builds transaction summary and transaction leg event in the format expected by Central's API Observer -* Uses libbeat to publish the events to Condor - -## Prerequisites -Kong Traceability agent requires **global deployment** of the below plugins in order to generate transaction summary and transaction leg event for all Kong's proxies -* [Correlation ID Plugin](https://docs.konghq.com/hub/kong-inc/correlation-id/) used for transaction ID -* [HTTP Log Plugin](https://docs.konghq.com/hub/kong-inc/http-log/) used to get the request logs associated with Kong proxy invocation - -## Build - -In order to build, run -```shell -make build-trace -``` - -## Configuration - -Configuration can be provided via kong_traceability_agent.yml under **traceability** folder - -## Run - -In order to run, make sure you are in **traceability** folder and run -```shell -make run -``` - From 4c705a1309a94a4365b1503a81f03c0887ba5afc Mon Sep 17 00:00:00 2001 From: Martin Look Date: Fri, 5 Feb 2021 12:57:48 +0100 Subject: [PATCH 24/76] Fix default YAML file for traceability agent. --- default_kong_traceability_agent.yml | 31 +++++++++++++++-------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/default_kong_traceability_agent.yml b/default_kong_traceability_agent.yml index 0393af8..5659287 100644 --- a/default_kong_traceability_agent.yml +++ b/default_kong_traceability_agent.yml @@ -1,19 +1,20 @@ # this is a sample config file. Copy the content of this file to a new file named kong_traceability_agent.yml -central: - environment: - mode: publishToEnvironment - organizationID: "" - platformURL: https://platform.axway.com - pollInterval: 20s - team: "Default Team" - url: https://apicentral.axway.com - auth: - clientID: - privateKey: - publicKey: - realm: Broker - timeout: 20s - url: https://login.axway.com/auth +kong_traceability_agent: + central: + environment: + mode: publishToEnvironment + organizationID: "" + platformURL: https://platform.axway.com + pollInterval: 20s + team: "Default Team" + url: https://apicentral.axway.com + auth: + clientID: + privateKey: + publicKey: + realm: Broker + timeout: 20s + url: https://login.axway.com/auth http_log_plugin_config: # Path used by Kong's HTTP Log plugin to send request logs From 831f1e6a2eef90c5cab0320a53a5cc9815eabad7 Mon Sep 17 00:00:00 2001 From: Sagar Date: Fri, 5 Feb 2021 10:42:08 -0700 Subject: [PATCH 25/76] Minor update --- pkg/processor/eventmapper.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/processor/eventmapper.go b/pkg/processor/eventmapper.go index 8fcedf7..933e00d 100644 --- a/pkg/processor/eventmapper.go +++ b/pkg/processor/eventmapper.go @@ -104,7 +104,7 @@ func (m *EventMapper) processQueryArgs(args map[string]string) string { func (m *EventMapper) createTransactionEvent(ktle KongTrafficLogEntry, txnid string) (*transaction.LogEvent, error) { httpProtocolDetails, err := transaction.NewHTTPProtocolBuilder(). - SetURI(ktle.Request.URI). + SetURI(ktle.UpstreamURI). SetMethod(ktle.Request.Method). SetArgs(m.processQueryArgs(ktle.Request.QueryString)). SetStatus(ktle.Response.Status, http.StatusText(ktle.Response.Status)). @@ -112,6 +112,7 @@ func (m *EventMapper) createTransactionEvent(ktle KongTrafficLogEntry, txnid str SetHeaders(m.buildHeaders(ktle.Request.Headers), m.buildHeaders(ktle.Response.Headers)). SetByteLength(ktle.Request.Size, ktle.Response.Size). SetLocalAddress(ktle.ClientIP, 0). // Could not determine local port for now + SetRemoteAddress("", "", ktle.Service.Port). SetSSLProperties(m.buildSSLInfoIfAvailable(ktle)). SetUserAgent(ktle.Request.Headers[userAgent]). Build() From 306156d396be578de9a681c1adee251978928d00 Mon Sep 17 00:00:00 2001 From: Sagar Date: Fri, 5 Feb 2021 11:40:07 -0700 Subject: [PATCH 26/76] Mask apikey header --- pkg/processor/eventmapper.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pkg/processor/eventmapper.go b/pkg/processor/eventmapper.go index 933e00d..e1c9c2d 100644 --- a/pkg/processor/eventmapper.go +++ b/pkg/processor/eventmapper.go @@ -18,8 +18,11 @@ import ( type EventMapper struct { } -const host = "host" -const userAgent = "user-agent" +const ( + host = "host" + userAgent = "user-agent" + redactedValue = "****************************" +) func (m *EventMapper) processMapping(kongTrafficLogEntry KongTrafficLogEntry) ([]*transaction.LogEvent, error) { centralCfg := agent.GetCentralConfig() @@ -77,10 +80,15 @@ func (m *EventMapper) getTransactionSummaryStatus(statusCode int) transaction.Tx } func (m *EventMapper) buildHeaders(headers map[string]string) string { + if headers["apikey"] != "" { + headers["apikey"] = redactedValue + } + jsonHeader, err := json.Marshal(headers) if err != nil { log.Error(err.Error()) } + return string(jsonHeader) } From b85a1e012eb9210bcd88996951df7a866c126dab Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Fri, 5 Feb 2021 12:02:19 -0700 Subject: [PATCH 27/76] Fetch plugins at the start of discovery (#8) --- pkg/gateway/cache.go | 2 -- pkg/gateway/client.go | 7 ++++--- pkg/gateway/definitions.go | 3 ++- pkg/kong/plugins.go | 2 -- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/pkg/gateway/cache.go b/pkg/gateway/cache.go index f2a40c0..9b546a0 100644 --- a/pkg/gateway/cache.go +++ b/pkg/gateway/cache.go @@ -3,7 +3,6 @@ package gateway import ( "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" "github.com/Axway/agent-sdk/pkg/cache" - "github.com/Axway/agent-sdk/pkg/util/log" ) // If the item is cached, return true @@ -33,7 +32,6 @@ func setCachedService(kongServiceId string, kongServiceName string, hash string, cachedService.kongServiceName = kongServiceName cachedService.hash = hash specCache.Set(kongServiceId, cachedService) - log.Infof("adding to the cache: '%s'. centralName: '%s'", kongServiceName, centralName) } } } diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 24c7f89..2b367d9 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -68,7 +68,8 @@ func (gc *Client) DiscoverAPIs() error { } // TODO: initCache should only run once initCache(apiServices) - + plugins := kutil.Plugins{PluginLister: gc.kongClient.GetKongPlugins()} + gc.plugins = plugins services, err := gc.kongClient.ListServices(context.Background()) if err != nil { log.Errorf("failed to get services: %s", err) @@ -139,8 +140,7 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se route := routes[0] - plugins := kutil.Plugins{PluginLister: gc.kongClient.GetKongPlugins()} - ep, err := plugins.GetEffectivePlugins(*route.ID, *service.ID) + ep, err := gc.plugins.GetEffectivePlugins(*route.ID, *service.ID) if err != nil { return fmt.Errorf("failed to get plugins for route %s: %w", *route.ID, err) } @@ -314,6 +314,7 @@ func doesServiceExists(serviceId string, services []*klib.Service) bool { } } log.Infof("Kong service '%s' no longer exists.", serviceId) + return false } diff --git a/pkg/gateway/definitions.go b/pkg/gateway/definitions.go index 344d3ef..16130e4 100644 --- a/pkg/gateway/definitions.go +++ b/pkg/gateway/definitions.go @@ -6,8 +6,8 @@ import ( "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" corecfg "github.com/Axway/agent-sdk/pkg/config" - config "github.com/Axway/agents-kong/pkg/config/discovery" + kutil "github.com/Axway/agents-kong/pkg/kong" ) type InstanceEndpoint = v1alpha1.ApiServiceInstanceSpecEndpoint @@ -18,6 +18,7 @@ type Client struct { kongClient kong.KongAPIClient apicClient CentralClient subscriptionManager *subscription.Manager + plugins kutil.Plugins } type KongAPI struct { diff --git a/pkg/kong/plugins.go b/pkg/kong/plugins.go index faf7248..c65631d 100644 --- a/pkg/kong/plugins.go +++ b/pkg/kong/plugins.go @@ -58,8 +58,6 @@ func (p *Plugins) GetEffectivePlugins(routeID, serviceID string) (map[string]*kl return nil, err } - // log.Infof("found %d plugins", len(plugins)) - pmap := map[string]*klib.Plugin{} for _, plugin := range plugins { From 90dff9a49245fe3a6f828fff8ed433e993166085 Mon Sep 17 00:00:00 2001 From: Victor Buciuc Date: Fri, 5 Feb 2021 15:03:08 -0700 Subject: [PATCH 28/76] use route.ID for proxy id. this enables the observer ui to correlate back to the APIService and allow filtering --- pkg/processor/eventmapper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/processor/eventmapper.go b/pkg/processor/eventmapper.go index e1c9c2d..c7a4f33 100644 --- a/pkg/processor/eventmapper.go +++ b/pkg/processor/eventmapper.go @@ -157,7 +157,7 @@ func (m *EventMapper) createSummaryEvent(ktle KongTrafficLogEntry, teamID string ktle.Request.URI, ktle.Request.URL). SetDuration(ktle.Latencies.Request). - SetProxy(transaction.FormatProxyID(ktle.Service.ID), + SetProxy(transaction.FormatProxyID(ktle.Route.ID), ktle.Service.Name, 1) From d60bff6e397a01c47bc8e09d1272177921eb96cb Mon Sep 17 00:00:00 2001 From: Victor Buciuc Date: Fri, 5 Feb 2021 15:04:09 -0700 Subject: [PATCH 29/76] transaction event and summary reflect the client<->kong interaction not kong<->backend --- pkg/processor/eventmapper.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/processor/eventmapper.go b/pkg/processor/eventmapper.go index c7a4f33..3cda66d 100644 --- a/pkg/processor/eventmapper.go +++ b/pkg/processor/eventmapper.go @@ -112,7 +112,7 @@ func (m *EventMapper) processQueryArgs(args map[string]string) string { func (m *EventMapper) createTransactionEvent(ktle KongTrafficLogEntry, txnid string) (*transaction.LogEvent, error) { httpProtocolDetails, err := transaction.NewHTTPProtocolBuilder(). - SetURI(ktle.UpstreamURI). + SetURI(ktle.Request.URI). SetMethod(ktle.Request.Method). SetArgs(m.processQueryArgs(ktle.Request.QueryString)). SetStatus(ktle.Response.Status, http.StatusText(ktle.Response.Status)). @@ -135,10 +135,10 @@ func (m *EventMapper) createTransactionEvent(ktle KongTrafficLogEntry, txnid str SetTransactionID(txnid). SetID("leg0"). SetParentID(""). - SetSource("client_ip"). - SetDestination("backend_api"). + SetSource(ktle.ClientIP). + SetDestination(ktle.Request.Headers[host]). SetDuration(ktle.Latencies.Request). - SetDirection("outbound"). + SetDirection("inbound"). SetStatus(m.getTransactionEventStatus(ktle.Response.Status)). SetProtocolDetail(httpProtocolDetails). Build() From 906daf7bca2e5f5814c8209badc3f5eb5075147f Mon Sep 17 00:00:00 2001 From: Daniel Tabuenca Velasco Date: Tue, 9 Feb 2021 15:22:23 +0100 Subject: [PATCH 30/76] Added png files --- png/KongFilePlugin.png | Bin 0 -> 145078 bytes png/KongHTTPPlugin.png | Bin 0 -> 144854 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 png/KongFilePlugin.png create mode 100644 png/KongHTTPPlugin.png diff --git a/png/KongFilePlugin.png b/png/KongFilePlugin.png new file mode 100644 index 0000000000000000000000000000000000000000..919fa76a1b0746c3e45c0b532eadff2fe8e30d1b GIT binary patch literal 145078 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ΝG-31`C4=@|c1`lrYo?V_-##h36>p8WI)xj#HHs3)3+v;M5A_HC5nzoO=2czo=~pw5>z)t_bW zV}Qep<|<1o4W*vU0z|@MSuYJCZX@MqOf~o#;<#|JCiU4>m52*WwaDUhaj55 zWz&%zAq2|+G(pu5e48w1xg8w_zHq(iUSiosW#r_nWFttm2V}PW{CW~;@CA44)=B4p zbhCbeo)ZrYG)d$rO)LXCb|m5lAptUojL_di_L>H^fu~`FY#%(la^5w>uJ-b+Cyl-1 z$|M2z5ihjZEWNBMIA4jU?Y^rxc%3aFF`>y?<9j%8wbzC#>GkOQf0_s_Ep0Y(8u=)X#1c2miEyr=aZvA4`EAs z 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 BV7veT literal 0 HcmV?d00001 diff --git a/png/KongHTTPPlugin.png b/png/KongHTTPPlugin.png new file mode 100644 index 0000000000000000000000000000000000000000..881457f3fc403632a5f128bdb4c8cabcb2e8f4f9 GIT binary patch literal 144854 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 literal 0 HcmV?d00001 From 18eb4ae08de3bf0e82c54f2f5d2689b313afc503 Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Wed, 3 Mar 2021 09:14:20 -0700 Subject: [PATCH 31/76] Update SetEndpoint based on sdk changes (#11) --- go.mod | 2 +- go.sum | 6 ++++-- pkg/gateway/client.go | 5 ++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 7cf0a72..47a3c44 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Axway/agents-kong go 1.13 require ( - github.com/Axway/agent-sdk v0.0.20-0.20210204223503-cc5b7758ff13 + github.com/Axway/agent-sdk v0.0.22-0.20210302163901-269d041fbfe1 github.com/Shopify/sarama v1.26.4 // indirect github.com/docker/docker v1.13.1 // indirect github.com/dustin/go-humanize v1.0.0 // indirect diff --git a/go.sum b/go.sum index b5a1882..08026f3 100644 --- a/go.sum +++ b/go.sum @@ -19,8 +19,8 @@ code.cloudfoundry.org/go-loggregator v7.4.0+incompatible/go.mod h1:KPBTRqj+y738N code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:sk5LnIjB/nIEU7yP5sDQExVm62wu0pBh3yrElngUisI= code.cloudfoundry.org/rfc5424 v0.0.0-20180905210152-236a6d29298a/go.mod h1:tkZo8GtzBjySJ7USvxm4E36lNQw1D3xM6oKHGqdaAJ4= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Axway/agent-sdk v0.0.20-0.20210204223503-cc5b7758ff13 h1:J8SEyRi30hr0SzLLLbinaEVU1kMmU+9RVasdcBP/ZTU= -github.com/Axway/agent-sdk v0.0.20-0.20210204223503-cc5b7758ff13/go.mod h1:fOaWmFFg1eDheNJZNe2+T/jRwfSm8AWcap1p+ytBv8I= +github.com/Axway/agent-sdk v0.0.22-0.20210302163901-269d041fbfe1 h1:e2nov6XK+Kclh0rWYBZ+PwHuk/EGADl+XdGG0sTHgKE= +github.com/Axway/agent-sdk v0.0.22-0.20210302163901-269d041fbfe1/go.mod h1:zNSqClCMSbQefg6v720wB2tGLM3/m9hKL5flqAvTILo= github.com/Azure/azure-amqp-common-go/v3 v3.0.0/go.mod h1:SY08giD/XbhTz07tJdpw1SoxQXHPN30+DI3Z04SYqyg= github.com/Azure/azure-event-hubs-go/v3 v3.1.2/go.mod h1:hR40byNJjKkS74+3RhloPQ8sJ8zFQeJ920Uk3oYY0+k= github.com/Azure/azure-pipeline-go v0.1.8/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg= @@ -313,6 +313,8 @@ github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEo github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorhill/cronexpr v0.0.0-20161205141322-d520615e531a/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= +github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 h1:f0n1xnMSmBLzVfsMMvriDyA75NB/oBgILX2GcHXIQzY= +github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I= github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 2b367d9..eabac58 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -293,10 +293,13 @@ func (ka *KongAPI) buildServiceBody() (apic.ServiceBody, error) { SetTitle(ka.name). SetURL(ka.url). SetVersion(ka.version). - SetServiceEndpoints(ka.endpoints). SetAuthPolicy(ka.subscriptionInfo.APICPolicyName). SetSubscriptionName(ka.subscriptionInfo.SchemaName) + for _, ep := range ka.endpoints { + body.SetServiceEndpoint(ep.Protocol, ep.Host, ep.Port, ep.Routing.BasePath) + } + sb, err := body.Build() // TODO: add set method for NameToPush From ddfa7f95b004a1daaa34277910149cbdd3ca5a75 Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Thu, 22 Apr 2021 14:39:38 -0700 Subject: [PATCH 32/76] AddServiceEndpoint change (#12) Co-authored-by: Trevor Johnson --- go.mod | 2 +- go.sum | 10 ++++++++-- pkg/gateway/client.go | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 47a3c44..e0ef711 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Axway/agents-kong go 1.13 require ( - github.com/Axway/agent-sdk v0.0.22-0.20210302163901-269d041fbfe1 + github.com/Axway/agent-sdk v1.0.20210421 github.com/Shopify/sarama v1.26.4 // indirect github.com/docker/docker v1.13.1 // indirect github.com/dustin/go-humanize v1.0.0 // indirect diff --git a/go.sum b/go.sum index 08026f3..d985c7e 100644 --- a/go.sum +++ b/go.sum @@ -19,8 +19,8 @@ code.cloudfoundry.org/go-loggregator v7.4.0+incompatible/go.mod h1:KPBTRqj+y738N code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:sk5LnIjB/nIEU7yP5sDQExVm62wu0pBh3yrElngUisI= code.cloudfoundry.org/rfc5424 v0.0.0-20180905210152-236a6d29298a/go.mod h1:tkZo8GtzBjySJ7USvxm4E36lNQw1D3xM6oKHGqdaAJ4= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Axway/agent-sdk v0.0.22-0.20210302163901-269d041fbfe1 h1:e2nov6XK+Kclh0rWYBZ+PwHuk/EGADl+XdGG0sTHgKE= -github.com/Axway/agent-sdk v0.0.22-0.20210302163901-269d041fbfe1/go.mod h1:zNSqClCMSbQefg6v720wB2tGLM3/m9hKL5flqAvTILo= +github.com/Axway/agent-sdk v1.0.20210421 h1:sZBM0OPMlpRwkf1y6jRSEsEC3cFT5eds6hoE6usKvfE= +github.com/Axway/agent-sdk v1.0.20210421/go.mod h1:ESIGxeiVC5Cza+MYgj5yGePQNjkT8diz4HxkQBCHwFk= github.com/Azure/azure-amqp-common-go/v3 v3.0.0/go.mod h1:SY08giD/XbhTz07tJdpw1SoxQXHPN30+DI3Z04SYqyg= github.com/Azure/azure-event-hubs-go/v3 v3.1.2/go.mod h1:hR40byNJjKkS74+3RhloPQ8sJ8zFQeJ920Uk3oYY0+k= github.com/Azure/azure-pipeline-go v0.1.8/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg= @@ -209,6 +209,8 @@ github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkg github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= github.com/emersion/go-smtp v0.13.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/proto v1.9.0 h1:l0QiNT6Qs7Yj0Mb4X6dnWBQer4ebei2BFcgQLbGqUDc= +github.com/emicklei/proto v1.9.0/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= 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.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -219,6 +221,8 @@ github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8 github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/frankban/quicktest v1.4.1 h1:Wv2VwvNn73pAdFIVUQRXYDFp31lXKbqblIXo/Q5GPSg= github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= +github.com/gabriel-vasile/mimetype v1.1.2 h1:gaPnPcNor5aZSVCJVSGipcpbgMWiAAj9z182ocSGbHU= +github.com/gabriel-vasile/mimetype v1.1.2/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To= github.com/garyburd/redigo v1.0.1-0.20160525165706-b8dc90050f24/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc= github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= @@ -284,6 +288,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw 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/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= github.com/google/go-github/v29 v29.0.2/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index eabac58..3fb75d7 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -297,7 +297,7 @@ func (ka *KongAPI) buildServiceBody() (apic.ServiceBody, error) { SetSubscriptionName(ka.subscriptionInfo.SchemaName) for _, ep := range ka.endpoints { - body.SetServiceEndpoint(ep.Protocol, ep.Host, ep.Port, ep.Routing.BasePath) + body.AddServiceEndpoint(ep.Protocol, ep.Host, ep.Port, ep.Routing.BasePath) } sb, err := body.Build() From 4fc47dddf34f84a89e0e9d1e7cfa787511b8ea8d Mon Sep 17 00:00:00 2001 From: Trevor Johnson Date: Thu, 7 Oct 2021 15:13:57 -0700 Subject: [PATCH 33/76] handle error when creating gateway client (#14) --- pkg/cmd/discovery/discoveryCmd.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/cmd/discovery/discoveryCmd.go b/pkg/cmd/discovery/discoveryCmd.go index 8e75fec..5e97d66 100644 --- a/pkg/cmd/discovery/discoveryCmd.go +++ b/pkg/cmd/discovery/discoveryCmd.go @@ -40,6 +40,10 @@ func run() error { stopChan = make(chan struct{}) gatewayClient, err := gateway.NewClient(agentConfig) + if err != nil { + return err + } + go func() { for { err = gatewayClient.DiscoverAPIs() From 4cf775edb48864febc8f21f7de31b22e427ca90d Mon Sep 17 00:00:00 2001 From: dfeldick Date: Wed, 17 Aug 2022 10:37:16 -0700 Subject: [PATCH 34/76] APIGOV-23288 - add Apache license --- LICENSE | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + 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. From b173b29a8573ee22139768fb902579305d57780a Mon Sep 17 00:00:00 2001 From: rathnapandi Date: Thu, 3 Aug 2023 21:14:27 -0700 Subject: [PATCH 35/76] Update SDK version, docker compose for kong open source gateway and remove cache for discovery. Catalog subscription is removed. --- docker-compose.yml | 71 ++ go.mod | 117 +- go.sum | 1328 +++++++++++++++++++++++ pkg/gateway/cache.go | 53 - pkg/gateway/centralclient.go | 28 - pkg/gateway/client.go | 220 ++-- pkg/gateway/definitions.go | 6 +- pkg/kong/kongclient.go | 8 +- pkg/subscription/subscriptionmanager.go | 2 +- 9 files changed, 1593 insertions(+), 240 deletions(-) create mode 100644 docker-compose.yml delete mode 100644 pkg/gateway/cache.go diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..a1a3dc7 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,71 @@ +version: '3.7' + +services: + kong-db: + image: postgres:13 + environment: + POSTGRES_USER: kong + POSTGRES_DB: kong + POSTGRES_PASSWORD: kongpass + networks: + - kong-net + ports: + - "5432:5432" + kong-migration: + image: kong:3.3.1 + command: kong migrations bootstrap + environment: + KONG_ADMIN_ACCESS_LOG: /dev/stdout + KONG_ADMIN_ERROR_LOG: /dev/stderr + KONG_ADMIN_LISTEN: '0.0.0.0:8001' + # KONG_DATABASE: "off" + KONG_DATABASE: postgres + KONG_PG_HOST: kong-db + KONG_PG_PASSWORD: kongpass + KONG_PASSWORD: test + # KONG_DECLARATIVE_CONFIG: /usr/local/kong/declarative/kong.yml + KONG_PROXY_ACCESS_LOG: /dev/stdout + KONG_PROXY_ERROR_LOG: /dev/stderr + networks: + - kong-net + depends_on: + - kong-db + kong: + image: kong:3.3.1 + environment: + KONG_ADMIN_ACCESS_LOG: /dev/stdout + KONG_ADMIN_ERROR_LOG: /dev/stderr + KONG_ADMIN_LISTEN: '0.0.0.0:8001' +# KONG_DATABASE: "off" + KONG_DATABASE: postgres + KONG_PG_HOST: kong-db + KONG_PG_PASSWORD: kongpass + KONG_PASSWORD: test +# KONG_DECLARATIVE_CONFIG: /usr/local/kong/declarative/kong.yml + KONG_PROXY_ACCESS_LOG: /dev/stdout + KONG_PROXY_ERROR_LOG: /dev/stderr +# volumes: +# - ./kong/:/usr/local/kong/declarative + networks: + - kong-net + ports: + - "8000:8000/tcp" + - "127.0.0.1:8001:8001/tcp" + - "8443:8443/tcp" + - "127.0.0.1:8444:8444/tcp" + healthcheck: + test: ["CMD", "kong", "health"] + interval: 10s + timeout: 10s + retries: 10 + restart: on-failure + deploy: + restart_policy: + condition: on-failure + depends_on: + - kong-db + - kong-migration + +networks: + kong-net: + external: false \ No newline at end of file diff --git a/go.mod b/go.mod index e0ef711..1357ddb 100644 --- a/go.mod +++ b/go.mod @@ -1,44 +1,119 @@ module github.com/Axway/agents-kong -go 1.13 +go 1.18 require ( - github.com/Axway/agent-sdk v1.0.20210421 + github.com/Axway/agent-sdk v1.1.58 + github.com/elastic/beats/v7 v7.17.5 + github.com/google/uuid v1.3.0 + github.com/kong/go-kong v0.46.0 + github.com/sirupsen/logrus v1.9.3 + github.com/tidwall/gjson v1.14.4 +) + +require ( + 4d63.com/tz v1.1.1-0.20191124060701-6d37baae851b // indirect github.com/Shopify/sarama v1.26.4 // indirect + github.com/armon/go-radix v1.0.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/dgrijalva/jwt-go v3.2.1-0.20190620180102-5e25c22bd5d6+incompatible // indirect github.com/docker/docker v1.13.1 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/eapache/go-resiliency v1.2.0 // indirect - github.com/elastic/beats/v7 v7.7.1 + github.com/elastic/elastic-agent-client/v7 v7.0.0-20220607160924-1a71765a8bbe // indirect + github.com/elastic/go-libaudit v0.4.0 // indirect + github.com/elastic/go-licenser v0.4.1 // indirect + github.com/elastic/go-sysinfo v1.8.1 // indirect + github.com/elastic/go-ucfg v0.8.6 // indirect + github.com/elastic/go-windows v1.0.1 // indirect + github.com/emicklei/proto v1.9.2 // indirect + github.com/fatih/color v1.13.0 // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/gabriel-vasile/mimetype v1.4.0 // indirect github.com/garyburd/redigo v1.6.0 // indirect - github.com/google/uuid v1.2.0 - github.com/googleapis/gnostic v0.3.1 // indirect + github.com/getkin/kin-openapi v0.76.0 // indirect + github.com/ghodss/yaml v1.0.0 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/gofrs/uuid v4.2.0+incompatible // indirect + github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/imdario/mergo v0.3.9 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/jcchavezs/porto v0.4.0 // indirect github.com/jcmturner/gofork v1.0.0 // indirect + github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect + github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/cpuid v1.3.1 // indirect - github.com/kong/go-kong v0.15.0 - github.com/kr/pretty v0.2.0 // indirect - github.com/miekg/dns v1.1.29 // indirect - github.com/mitchellh/hashstructure v1.0.0 // indirect - github.com/pelletier/go-toml v1.8.0 // indirect - github.com/pierrec/lz4 v2.5.2+incompatible // indirect - github.com/sirupsen/logrus v1.6.0 - github.com/spf13/afero v1.3.0 // indirect - github.com/spf13/cast v1.3.1 // indirect - github.com/tidwall/gjson v1.6.8 - gopkg.in/ini.v1 v1.57.0 // indirect + github.com/kong/semver/v4 v4.0.1 // indirect + github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect + github.com/lestrrat-go/blackmagic v1.0.1 // indirect + github.com/lestrrat-go/httpcc v1.0.1 // indirect + github.com/lestrrat-go/iter v1.0.2 // indirect + github.com/lestrrat-go/jwx v1.2.26 // indirect + github.com/lestrrat-go/option v1.0.1 // indirect + github.com/magefile/mage v1.13.0 // indirect + github.com/magiconair/properties v1.8.6 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mitchellh/hashstructure v1.1.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml/v2 v2.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/procfs v0.7.3 // indirect + github.com/reviewdog/reviewdog v0.9.17 // indirect + github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect + github.com/snowzach/rotatefilehook v0.0.0-20220211133110-53752135082d // indirect + github.com/spf13/afero v1.8.2 // indirect + github.com/spf13/cast v1.5.0 // indirect + github.com/spf13/cobra v1.5.0 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.12.0 // indirect + github.com/subosito/gotenv v1.4.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect + github.com/urso/magetools v0.0.0-20200106130147-61080ed7b22b // indirect + go.elastic.co/apm v1.15.0 // indirect + go.elastic.co/ecszap v1.0.1 // indirect + go.elastic.co/fastjson v1.1.0 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.8.0 // indirect + go.uber.org/zap v1.21.0 // indirect + golang.org/x/crypto v0.9.0 // indirect + golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect + golang.org/x/mod v0.9.0 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/text v0.9.0 // indirect + golang.org/x/tools v0.7.0 // indirect + google.golang.org/genproto v0.0.0-20220714211235-042d03aeabc9 // indirect + google.golang.org/grpc v1.48.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/jcmturner/gokrb5.v7 v7.5.0 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + howett.net/plist v1.0.0 // indirect ) replace ( github.com/Shopify/sarama => github.com/elastic/sarama v0.0.0-20191122160421-355d120d0970 github.com/docker/docker => github.com/docker/engine v17.12.0-ce-rc1.0.20190717161051-705d9623b7c1+incompatible - github.com/docker/go-plugins-helpers => github.com/elastic/go-plugins-helpers v0.0.0-20200207104224-bdf17607b79f github.com/dop251/goja => github.com/andrewkroh/goja v0.0.0-20190128172624-dd2ac4456e20 - github.com/fsnotify/fsevents => github.com/elastic/fsevents v0.0.0-20181029231046-e1d381a4d270 github.com/fsnotify/fsnotify => github.com/adriansr/fsnotify v0.0.0-20180417234312-c9bbe1f46f1d - github.com/google/gopacket => github.com/adriansr/gopacket v1.1.18-0.20200327165309-dd62abfa8a41 - github.com/insomniacslk/dhcp => github.com/elastic/dhcp v0.0.0-20200227161230-57ec251c7eb3 // indirect k8s.io/api => k8s.io/api v0.17.0 k8s.io/apimachinery => k8s.io/apimachinery v0.17.0 k8s.io/client-go => k8s.io/client-go v0.17.0 diff --git a/go.sum b/go.sum index d985c7e..d84b547 100644 --- a/go.sum +++ b/go.sum @@ -6,14 +6,61 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT 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.44.3/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.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= +cloud.google.com/go/kms v1.0.0/go.mod h1:nhUehi+w7zht2XrUfvTRNpxrfayBHqP4lu2NSywui/0= +cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.17.1/go.mod h1:4qDxMr1WsM9+aQAz36ltDwCIM+R0QdlseyFjBuNvnss= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= code.cloudfoundry.org/go-diodes v0.0.0-20190809170250-f77fb823c7ee/go.mod h1:Jzi+ccHgo/V/PLQUaQ6hnZcC1c4BS790gx21LRRui4g= code.cloudfoundry.org/go-loggregator v7.4.0+incompatible/go.mod h1:KPBTRqj+y738Nhf1+g4JHFaBU8j7dedirR5ETNHvMXU= code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:sk5LnIjB/nIEU7yP5sDQExVm62wu0pBh3yrElngUisI= @@ -21,45 +68,91 @@ code.cloudfoundry.org/rfc5424 v0.0.0-20180905210152-236a6d29298a/go.mod h1:tkZo8 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Axway/agent-sdk v1.0.20210421 h1:sZBM0OPMlpRwkf1y6jRSEsEC3cFT5eds6hoE6usKvfE= github.com/Axway/agent-sdk v1.0.20210421/go.mod h1:ESIGxeiVC5Cza+MYgj5yGePQNjkT8diz4HxkQBCHwFk= +github.com/Axway/agent-sdk v1.1.58 h1:wnrnuRKus/aZPLhOPZr8FiCPbCQ4VJBra/Gp7iVFdbs= +github.com/Axway/agent-sdk v1.1.58/go.mod h1:xe6dIpQxE0LcSR+ssGKL4mfyLFbrLohdrB9iMYFUCdU= github.com/Azure/azure-amqp-common-go/v3 v3.0.0/go.mod h1:SY08giD/XbhTz07tJdpw1SoxQXHPN30+DI3Z04SYqyg= +github.com/Azure/azure-amqp-common-go/v3 v3.2.1/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI= github.com/Azure/azure-event-hubs-go/v3 v3.1.2/go.mod h1:hR40byNJjKkS74+3RhloPQ8sJ8zFQeJ920Uk3oYY0+k= +github.com/Azure/azure-event-hubs-go/v3 v3.3.15/go.mod h1:xgDvUi1+8/bb11WTEaU7VwZREYufzKzjWE4YiPZixb0= github.com/Azure/azure-pipeline-go v0.1.8/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg= github.com/Azure/azure-pipeline-go v0.1.9/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= +github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v37.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v51.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v59.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-storage-blob-go v0.6.0/go.mod h1:oGfmITT1V6x//CswqY2gtAHND+xIP64/qL7a5QJix0Y= github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= github.com/Azure/go-amqp v0.12.6/go.mod h1:qApuH6OFTSKZFmCOxccvAv5rLizBQf4v8pRmG138DPo= +github.com/Azure/go-amqp v0.16.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= 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.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= github.com/Azure/go-autorest/autorest v0.9.4/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= +github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= +github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/adal v0.9.15/go.mod h1:tGMin8I49Yij6AQ+rvV+Xa/zwxYQB5hmsd6DkfAx2+A= github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM= github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= +github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= +github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= 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/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Microsoft/go-winio v0.4.9/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +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 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA= 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/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.1/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 v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= +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/PaesslerAG/gval v1.0.0/go.mod h1:y/nm5yEyTeX6av0OfKJNp9rBNj2XrGhAf5+v24IBN1I= +github.com/PaesslerAG/jsonpath v0.1.0/go.mod h1:4BzmtoM/PI8fPO4aQGIusjGxGir2BzcV0grWtFzq1Y8= +github.com/PaesslerAG/jsonpath v0.1.1/go.mod h1:lVboNxFGal/VwW6d9JzIy56bUsYAP6tH/x80vjnCseY= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +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/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20170221213301-9f32b5905fd6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= @@ -72,31 +165,57 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy 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/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/andrewkroh/goja v0.0.0-20190128172624-dd2ac4456e20 h1:7rj9qZ63knnVo2ZeepYHvHuRdG76f3tRUTdIQDzRBeI= github.com/andrewkroh/goja v0.0.0-20190128172624-dd2ac4456e20/go.mod h1:cI59GRkC2FRaFYtgbYEqMlgnnfvAwXzjojyZKXwklNg= github.com/andrewkroh/sys v0.0.0-20151128191922-287798fe3e43/go.mod h1:tJPYQG4mnMeUtQvQKNkbsFrnmZOg59Qnf8CcctFv5v4= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/antlr/antlr4 v0.0.0-20200820155224-be881fa6b91d/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y= +github.com/apache/thrift v0.13.1-0.20200603211036-eac4d0c79a5f/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apoydence/eachers v0.0.0-20181020210610-23942921fe77/go.mod h1:bXvGk6IkT1Agy7qzJ+DjIw/SJ1AaB3AvAuMDVV+Vkoo= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-lambda-go v1.6.0/go.mod h1:zUsUQhAUjYzR8AuduJPCfhBuKWUaDbQiPOG+ouzmE1A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/aws/aws-sdk-go v1.19.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.9.0/go.mod h1:sa1GePZ/LfBGI4dSq30f6uR4Tthll8axxtEPvlpXZ8U= +github.com/aws/aws-sdk-go-v2 v0.24.0/go.mod h1:2LhT7UgHOXK3UXONKI5OMgIyoQL6zTAw/jwIeX6yqzw= github.com/awslabs/goformation/v3 v3.1.0/go.mod h1:hQ5RXo3GNm2laHWKizDzU5DsDy+yNcenSca2UxN0850= github.com/awslabs/goformation/v4 v4.1.0/go.mod h1:MBDN7u1lMNDoehbFuO4uPvgwPeolTMA2TzX1yO6KlxI= +github.com/awslabs/kinesis-aggregation/go v0.0.0-20200810181507-d352038274c0/go.mod h1:SghidfnxvX7ribW6nHI7T+IBbc9puZ9kk5Tx/88h8P4= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +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/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= github.com/blang/semver v0.0.0-20190414102917-ba2c2ddd8906/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.1.0+incompatible h1:7hqmJYuaEK3qwVjWubYiht3j93YI0WQBuysxHIfUriU= 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/bradleyfalzon/ghinstallation v1.1.0/go.mod h1:p7iD8KytOOKg2wCqbwvJlq4JGpYMjwjkiqdyUqOIHLI= +github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/bsm/sarama-cluster v2.1.14-0.20180625083203-7e67d87a6b3f+incompatible/go.mod h1:r7ao+4tTNXvWm+VRpRJchr2kQhqxgmAp2iEX5W96gMM= +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/cavaliercoder/badio v0.0.0-20160213150051-ce5280129e9e/go.mod h1:V284PjgVwSk4ETmz84rpu9ehpGg7swlIH8npP9k2bGw= github.com/cavaliercoder/go-rpm v0.0.0-20190131055624-7a9c54e3d83e/go.mod h1:AZIh1CCnMrcVm6afFf96PBvE2MRpWFco91z8ObJtgDY= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -104,63 +223,197 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= +github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= 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/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudfoundry-community/go-cfclient v0.0.0-20190808214049-35bcce23fc5f/go.mod h1:RtIewdO+K/czvxvIFCMbPyx7jdxSLL1RZ+DA/Vk8Lwg= +github.com/cloudfoundry/noaa v2.1.0+incompatible/go.mod h1:5LmacnptvxzrTvMfL9+EJhgkUfIgcwI61BVSTh47ECo= github.com/cloudfoundry/sonde-go v0.0.0-20171206171820-b33733203bb4/go.mod h1:GS0pCHd7onIsewbw8Ue9qa9pZPv2V88cUZDttK6KzgI= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +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/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/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.3.3/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/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= +github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= 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-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY= +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/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-20190816180239-bda0ff6ed73c/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/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/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/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/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.1-coreos.6.0.20180318001526-af9db2027c98/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= 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/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +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/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/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 v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +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/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cucumber/godog v0.8.1/go.mod h1:vSh3r/lM+psC1BPXvdkSEuNjmXfpVqrMGYAElF6hxnA= +github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +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 v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/davecgh/go-xdr v0.0.0-20161123171359-e6a2ba005892/go.mod h1:CTDl0pzVzE5DEzZhPfvhY/9sPFMQIxaJ9VAMs9AagrE= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc= +github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= github.com/devigned/tab v0.1.2-0.20190607222403-0c15cf42f9a2/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= +github.com/dgraph-io/badger/v3 v3.2103.1/go.mod h1:dULbq6ehJ5K0cGW/1TQ9iSfUk0gbSiToDWmWmTsJ53E= +github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= +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/dgrijalva/jwt-go v3.2.1-0.20190620180102-5e25c22bd5d6+incompatible h1:4jGdduO4ceTJFKf0IhgaB8NJapGqKHwC2b4xQ/cXujM= github.com/dgrijalva/jwt-go v3.2.1-0.20190620180102-5e25c22bd5d6+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/digitalocean/go-libvirt v0.0.0-20180301200012-6075ea3c39a1/go.mod h1:PRcPVAAma6zcLpFd4GZrjR/MRpood3TamjKI2m/z/Uw= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dlclark/regexp2 v1.1.7-0.20171009020623-7632a260cbaf h1:uOWCk+L8abzw0BzmnCn7j7VT3g6bv9zW8fkR0yOP0Q4= github.com/dlclark/regexp2 v1.1.7-0.20171009020623-7632a260cbaf/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +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 h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.8.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/engine v17.12.0-ce-rc1.0.20190717161051-705d9623b7c1+incompatible h1:4Pnn+RsurVEiBbmqlRtzh77HLMiP4NaaqRHOOK4aPj8= github.com/docker/engine v17.12.0-ce-rc1.0.20190717161051-705d9623b7c1+incompatible/go.mod h1:3CPr2caMgTHxxIAZgEMd3uLYPDlRvPqCpyeRf6ncPcY= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +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-plugins-helpers v0.0.0-20181025120712-1e6269c305b8/go.mod h1:LFyLie6XcDbyKGeVK6bHe+9aJTYCxWLBg5IrJZOaXKA= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= 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/dolmen-go/contextio v0.0.0-20200217195037-68fc5150bcd5/go.mod h1:cxc20xI7fOgsFHWgt+PenlDDnMcrvh7Ocuj5hEFIdEk= github.com/dop251/goja_nodejs v0.0.0-20171011081505-adff31b136e6 h1:RrkoB0pT3gnjXhL/t10BSP1mcr/0Ldea2uMyuBr2SWk= github.com/dop251/goja_nodejs v0.0.0-20171011081505-adff31b136e6/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -176,12 +429,23 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFP github.com/eclipse/paho.mqtt.golang v1.2.1-0.20200121105743-0d940dd29fd2/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= github.com/elastic/beats/v7 v7.7.1 h1:aets27tEojy9IbpCW/X3CxlzObVjtMKyLpGk9RtXYNM= github.com/elastic/beats/v7 v7.7.1/go.mod h1:6wQ39q838+pC8Y927cbdfRWFnoOvni1+CTorV4lgpYA= +github.com/elastic/beats/v7 v7.17.5 h1:/cvFiUuXnIHzBnb7RzCfn06nydYbJyD9VIPv2N4UWG4= +github.com/elastic/beats/v7 v7.17.5/go.mod h1:nFsbsraCRGlck/aOwtfEJFKEyVBiDqxGvZ3ZES6sMn4= github.com/elastic/dhcp v0.0.0-20200227161230-57ec251c7eb3/go.mod h1:aPqzac6AYkipvp4hufTyMj5PDIphF3+At8zr7r51xjY= github.com/elastic/ecs v1.5.0 h1:/VEIBsRU4ecq2+U3RPfKNc6bFyomP6qnthYEcQZu8GU= github.com/elastic/ecs v1.5.0/go.mod h1:pgiLbQsijLOJvFR8OTILLu0Ni/R/foUNg0L+T6mU9b4= +github.com/elastic/ecs v1.12.0/go.mod h1:pgiLbQsijLOJvFR8OTILLu0Ni/R/foUNg0L+T6mU9b4= +github.com/elastic/elastic-agent-client/v7 v7.0.0-20210727140539-f0905d9377f6/go.mod h1:uh/Gj9a0XEbYoM4NYz4LvaBVARz3QXLmlNjsrKY9fTc= +github.com/elastic/elastic-agent-client/v7 v7.0.0-20220607160924-1a71765a8bbe h1:knHO5fYAT3+sLf64NxcOxdjGysPxsSMkQGB27vMS8TE= +github.com/elastic/elastic-agent-client/v7 v7.0.0-20220607160924-1a71765a8bbe/go.mod h1:fkvyUfFwyAG5OnMF0h+FV9sC0Xn9YLITwQpSuwungQs= github.com/elastic/fsevents v0.0.0-20181029231046-e1d381a4d270/go.mod h1:Msl1pdboCbArMF/nSCDUXgQuWTeoMmE/z8607X+k7ng= +github.com/elastic/go-concert v0.2.0/go.mod h1:HWjpO3IAEJUxOeaJOWXWEp7imKd27foxz9V5vegC/38= github.com/elastic/go-libaudit v0.4.0/go.mod h1:lNJ7gX+arohEQTwqinAc8xycVuFNqsaunba1mwcBdvE= +github.com/elastic/go-libaudit/v2 v2.2.0/go.mod h1:MM/l/4xV7ilcl+cIblL8Zn448J7RZaDwgNLE4gNKYPg= github.com/elastic/go-licenser v0.2.1/go.mod h1:D8eNQk70FOCVBl3smCGQt/lv7meBeQno2eI1S5apiHQ= +github.com/elastic/go-licenser v0.3.1/go.mod h1:D8eNQk70FOCVBl3smCGQt/lv7meBeQno2eI1S5apiHQ= +github.com/elastic/go-licenser v0.4.1 h1:1xDURsc8pL5zYT9R29425J3vkHdt4RT5TNEMeRN48x4= +github.com/elastic/go-licenser v0.4.1/go.mod h1:V56wHMpmdURfibNBggaSBfqgPxyT1Tldns1i87iTEvU= github.com/elastic/go-lookslike v0.3.0/go.mod h1:AhH+rdJux5RlVjs+6ej4jkvYyoNRkj2crxmqeHlj3hA= github.com/elastic/go-lumber v0.1.0 h1:HUjpyg36v2HoKtXlEC53EJ3zDFiDRn65d7B8dBHNius= github.com/elastic/go-lumber v0.1.0/go.mod h1:8YvjMIRYypWuPvpxx7WoijBYdbB7XIh/9FqSYQZTtxQ= @@ -189,80 +453,162 @@ github.com/elastic/go-perf v0.0.0-20191212140718-9c656876f595/go.mod h1:s09U1b4P github.com/elastic/go-plugins-helpers v0.0.0-20200207104224-bdf17607b79f/go.mod h1:OPGqFNdTS34kMReS5hPFtBhD9J8itmSDurs1ix2wx7c= github.com/elastic/go-seccomp-bpf v1.1.0 h1:jUzzDc6LyCtdolZdvL/26dad6rZ9vsc7xZ2eadKECAU= github.com/elastic/go-seccomp-bpf v1.1.0/go.mod h1:l+89Vy5BzjVcaX8USZRMOwmwwDScE+vxCFzzvQwN7T8= +github.com/elastic/go-seccomp-bpf v1.2.0/go.mod h1:l+89Vy5BzjVcaX8USZRMOwmwwDScE+vxCFzzvQwN7T8= github.com/elastic/go-structform v0.0.6 h1:wqeK4LwD2NNDOoRGTImE24S6pkCDVr8+oUSIkmChzLk= github.com/elastic/go-structform v0.0.6/go.mod h1:QrMyP3oM9Sjk92EVGLgRaL2lKt0Qx7ZNDRWDxB6khVs= +github.com/elastic/go-structform v0.0.9/go.mod h1:CZWf9aIRYY5SuKSmOhtXScE5uQiLZNqAFnwKR4OrIM4= +github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= github.com/elastic/go-sysinfo v1.3.0 h1:eb2XFGTMlSwG/yyU9Y8jVAYLIzU2sFzWXwo2gmetyrE= github.com/elastic/go-sysinfo v1.3.0/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= +github.com/elastic/go-sysinfo v1.7.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= +github.com/elastic/go-sysinfo v1.8.1 h1:4Yhj+HdV6WjbCRgGdZpPJ8lZQlXZLKDAeIkmQ/VRvi4= +github.com/elastic/go-sysinfo v1.8.1/go.mod h1:JfllUnzoQV/JRYymbH3dO1yggI3mV2oTKSXsDHM+uIM= github.com/elastic/go-txfile v0.0.7 h1:Yn28gclW7X0Qy09nSMSsx0uOAvAGMsp6XHydbiLVe2s= github.com/elastic/go-txfile v0.0.7/go.mod h1:H0nCoFae0a4ga57apgxFsgmRjevNCsEaT6g56JoeKAE= github.com/elastic/go-ucfg v0.7.0/go.mod h1:iaiY0NBIYeasNgycLyTvhJftQlQEUO2hpF+FX0JKxzo= github.com/elastic/go-ucfg v0.8.3 h1:leywnFjzr2QneZZWhE6uWd+QN/UpP0sdJRHYyuFvkeo= github.com/elastic/go-ucfg v0.8.3/go.mod h1:iaiY0NBIYeasNgycLyTvhJftQlQEUO2hpF+FX0JKxzo= +github.com/elastic/go-ucfg v0.8.6 h1:stUeyh2goTgGX+/wb9gzKvTv0YB0231LTpKUgCKj4U0= +github.com/elastic/go-ucfg v0.8.6/go.mod h1:4E8mPOLSUV9hQ7sgLEJ4bvt0KhMuDJa8joDT2QGAEKA= github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU= github.com/elastic/go-windows v1.0.1 h1:AlYZOldA+UJ0/2nBuqWdo90GFCgG9xuyw9SYzGUtJm0= github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss= github.com/elastic/gosigar v0.10.5 h1:GzPQ+78RaAb4J63unidA/JavQRKrB6s8IOzN6Ib59jo= github.com/elastic/gosigar v0.10.5/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= +github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/sarama v0.0.0-20191122160421-355d120d0970 h1:rSo6gsz4zOanqtJ5fmZYQJvEJnA5YsVOB25casIwqUw= github.com/elastic/sarama v0.0.0-20191122160421-355d120d0970/go.mod h1:fGP8eQ6PugKEI0iUETYYtnP6d1pH/bdDMTel1X5ajsU= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= +github.com/emersion/go-sasl v0.0.0-20211008083017-0b9dcfb154ac/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= github.com/emersion/go-smtp v0.13.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ= +github.com/emersion/go-smtp v0.15.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ= 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/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/proto v1.9.0 h1:l0QiNT6Qs7Yj0Mb4X6dnWBQer4ebei2BFcgQLbGqUDc= github.com/emicklei/proto v1.9.0/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= +github.com/emicklei/proto v1.9.2 h1:YX2MPuUfUi/h8v+yt4WD8cdj6bt9P3475d2zrL0iogM= +github.com/emicklei/proto v1.9.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.5.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/frankban/quicktest v1.4.1 h1:Wv2VwvNn73pAdFIVUQRXYDFp31lXKbqblIXo/Q5GPSg= github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= +github.com/fsnotify/fsevents v0.1.1/go.mod h1:+d+hS27T6k5J8CRaPLKFgwKYcpS7GwW3Ule9+SC2ZRc= +github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/gabriel-vasile/mimetype v1.1.2 h1:gaPnPcNor5aZSVCJVSGipcpbgMWiAAj9z182ocSGbHU= github.com/gabriel-vasile/mimetype v1.1.2/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To= +github.com/gabriel-vasile/mimetype v1.4.0 h1:Cn9dkdYsMIu56tGho+fqzh7XmvY2YyGU0FnbhiOsEro= +github.com/gabriel-vasile/mimetype v1.4.0/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8= +github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/garyburd/redigo v1.0.1-0.20160525165706-b8dc90050f24/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc= github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/getkin/kin-openapi v0.9.0 h1:/vaUQkiOR+vfFO3oilZentZTfAhz7OzXPhLdNas4q4w= github.com/getkin/kin-openapi v0.9.0/go.mod h1:zZQMFkVgRHCdhgb6ihCTIo9dyDZFvX0k/xAKqw1FhPw= +github.com/getkin/kin-openapi v0.76.0 h1:j77zg3Ec+k+r+GA3d8hBoXpAc6KX9TbBPrwQGBIy2sY= +github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= 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-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= 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-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.5-0.20190920104607-14974a1cf647/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +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/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +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/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +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-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-sourcemap/sourcemap v2.1.2+incompatible h1:0b/xya7BKGhXuqFESKM4oIiRo9WOt2ebz7KxfreD6ug= github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v2.20.0+incompatible/go.mod h1:N/mhXZITr/EQAOErEHciKvO1bFei2Lld2Ym6h96pdy0= +github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= +github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= github.com/gocarina/gocsv v0.0.0-20170324095351-ffef3ffc77be/go.mod h1:/oj50ZdPq/cUjA02lMZhijk5kR31SEydKyqah1OgBuo= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.5/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godror/godror v0.10.4/go.mod h1:9MVLtu25FBJBMHkPs0m3Ngf/VmwGcLpM2HS8PlNGw9U= github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/flock v0.7.2-0.20190320160742-5135e617513b h1:3QNh5Xo2pmr2nZXENtnztfpjej8XY8EPmvYxF5SzY9M= github.com/gofrs/flock v0.7.2-0.20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= +github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +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 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= 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= @@ -270,83 +616,184 @@ github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7 h1:5ZkaAPbicIKTF2I64qf5Fh8Aa83Q/dnOafMYV0OMwjA= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 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 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= 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/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.8.3/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= 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/flatbuffers v1.7.2-0.20170925184458-7a6b2bf521e9/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v1.12.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= 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 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= github.com/google/go-github/v29 v29.0.2/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= 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/gopacket v1.1.18-0.20191009163724-0ad7f2610e34/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= +github.com/google/licenseclassifier v0.0.0-20200402202327-879cb1424de0/go.mod h1:qsqn2hxC+vURpyBRygGUuinTO42MFRLcsmQ/P8v94+M= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +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-0.20190416172445-c2e93f3ae59f/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.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/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.3.1-0.20190624222214-25d8b0b66985/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= +github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorhill/cronexpr v0.0.0-20161205141322-d520615e531a/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 h1:f0n1xnMSmBLzVfsMMvriDyA75NB/oBgILX2GcHXIQzY= github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= +github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I= github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +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.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/h2non/filetype v1.1.1/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= 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/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= 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/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -354,36 +801,69 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.2-0.20190520140433-59383c442f7d/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-0.20180906183839-65a6292f0157 h1:uyodBE3xDz0ynKs1tLBU26wOQoEkAqqiY18DbZ+FZrA= github.com/hashicorp/hcl v1.0.1-0.20180906183839-65a6292f0157/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/nomad/api v0.0.0-20200303134319-e31695b5bbe6/go.mod h1:WKCL+tLVhN1D+APwH3JiTRZoxcdwRk86bWu1LVCUPaE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/haya14busa/go-actions-toolkit v0.0.0-20200105081403-ca0307860f01/go.mod h1:1DWDZmeYf0LX30zscWb7K9rUMeirNeBMd5Dum+seUhc= github.com/haya14busa/go-checkstyle v0.0.0-20170303121022-5e9d09f51fa1/go.mod h1:RsN5RGgVYeXpcXNtWyztD5VIe7VNSEqpJvF2iEH7QvI= github.com/haya14busa/secretbox v0.0.0-20180525171038-07c7ecf409f5/go.mod h1:FGO/dXIFZnan7KvvUSFk1hYMnoVNzB6NTMPrmke8SSI= +github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= github.com/imdario/mergo v0.3.9/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/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/insomniacslk/dhcp v0.0.0-20180716145214-633285ba52b2/go.mod h1:CfMdguCK66I5DAUJgGKyNz8aB6vO5dZzkm9Xep6WGvw= +github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= +github.com/jarcoal/httpmock v1.0.4/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= +github.com/jcchavezs/porto v0.1.0/go.mod h1:fESH0gzDHiutHRdX2hv27ojnOVFco37hg1W6E9EZF4A= +github.com/jcchavezs/porto v0.4.0 h1:Zj7RligrxmDdKGo6fBO2xYAHxEgrVBfs1YAja20WbV4= +github.com/jcchavezs/porto v0.4.0/go.mod h1:fESH0gzDHiutHRdX2hv27ojnOVFco37hg1W6E9EZF4A= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +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/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/josephspurrier/goversioninfo v0.0.0-20190209210621-63e6d1acd3dd/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE= github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -391,22 +871,38 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/justinas/nosurf v1.1.0/go.mod h1:ALpWdSbuNGy2lZWtyXdjkYv4edL23oSEgfBT1gPJ5BQ= +github.com/kardianos/service v1.2.1-0.20210728001519-a323c3813bc7/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM= +github.com/karrick/godirwalk v1.15.6/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= 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.8.2 h1:Bx0qjetmNjdFXASH02NSAREKpiaDwkO1DRZ3dV2KCcs= github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +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/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s= github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4= github.com/kong/go-kong v0.15.0 h1:9Y+7iqh7/0z8/BppAaLEV7ueSSyqK6lJOHFvqJnSSqM= github.com/kong/go-kong v0.15.0/go.mod h1:oF4kdI9l/a8ndDW2ayJA0yhDBpO8Qt2aLiJEv10hqnQ= +github.com/kong/go-kong v0.46.0 h1:9I6nlX63WymU5Sg+d13iZDVwpW5vXh8/v0zarU27dzI= +github.com/kong/go-kong v0.46.0/go.mod h1:41Sot1N/n8UHBp+gE/6nOw3vuzoHbhMSyU/zOS7VzPE= +github.com/kong/semver/v4 v4.0.1 h1:DIcNR8W3gfx0KabFBADPalxxsp+q/5COwIFkkhrFQ2Y= +github.com/kong/semver/v4 v4.0.1/go.mod h1:LImQ0oT15pJvSns/hs2laLca2zcYoHu5EsSNY0J6/QA= 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 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= @@ -416,38 +912,87 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= +github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= +github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80= +github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= +github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= +github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= +github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= +github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= +github.com/lestrrat-go/jwx v1.2.26 h1:4iFo8FPRZGDYe1t19mQP0zTRqA7n8HnJ5lkIiDvJcB0= +github.com/lestrrat-go/jwx v1.2.26/go.mod h1:MaiCdGbn3/cckbOFSCluJlJMmp9dmZm5hDuIkx8ftpQ= +github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= +github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.2-0.20190507191818-2ff3cb3adc01/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/magefile/mage v1.9.0 h1:t3AU2wNwehMCW97vuqQLtw6puppWXHO+O2MHo5a50XE= github.com/magefile/mage v1.9.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= +github.com/magefile/mage v1.11.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= +github.com/magefile/mage v1.13.0 h1:XtLJl8bcCM7EFoO8FyH8XK3t7G5hQAeK+i4tq+veT9M= +github.com/magefile/mage v1.13.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= +github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/markbates/pkger v0.17.0/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= +github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11/go.mod h1:Ah2dBMoxZEqk118as2T4u4fjfXarE0pPnMJaArZQZsI= github.com/mattn/go-colorable v0.0.8/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20191113090002-7c0f6868bffe/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-shellwords v1.0.7/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 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/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.25/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.29 h1:xHBEhR+t5RzcFJjBLJlax2daXOrTYtr9z4WdKEfWFzg= github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +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/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= @@ -456,11 +1001,24 @@ github.com/mitchellh/gox v1.0.1/go.mod h1:ED6BioOGXMswlXa2zxfh/xdd5QhwYliBFn9V18 github.com/mitchellh/hashstructure v0.0.0-20170116052023-ab25296c0f51/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9dGS02Q3Y= github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= +github.com/mitchellh/hashstructure v1.1.0 h1:P6P1hdjqAAknpY/M1CGipelZgp+4y9ja9kmUZPXP+H0= +github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/6d8ulp4AwfLKrmA= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg= github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +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/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +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/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 h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -468,107 +1026,217 @@ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lN github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +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/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= +github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= 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/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +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.5.0/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.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +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.2.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +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-rc1.0.20190228220655-ac19fd6e7483 h1:eFd3FsB01m/zNg/yBMYdm/XqiqCztcN9SVRPtGtzDHo= github.com/opencontainers/go-digest v1.0.0-rc1.0.20190228220655-ac19fd6e7483/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +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/image-spec v1.0.2-0.20190823105129-775207bd45b6 h1:yN8BPXVwMBAm3Cuvh1L5XE8XpvYRMdsVLd82ILprhUU= github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6/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/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= 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/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/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/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/osquery/osquery-go v0.0.0-20210622151333-99b4efa62ec5/go.mod h1:JKR5QhjsYdnIPY7hakgas5sxf8qlA/9wQnLqaMfWdcg= +github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= +github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= +github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2/go.mod h1:L3UMQOThbttwfYRNFOWLLVXMhk5Lkio4GGOtw5UrxS0= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw= github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= +github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw= +github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pierrec/lz4 v2.2.6+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.6.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrre/gotestcover v0.0.0-20160113212533-7b94f124d338/go.mod h1:4xpMLz7RBWyB+ElzHu8Llua96TRCB3YwX+l5EP1wmHk= +github.com/pierrre/gotestcover v0.0.0-20160517101806-924dca7d15f0/go.mod h1:4xpMLz7RBWyB+ElzHu8Llua96TRCB3YwX+l5EP1wmHk= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1-0.20170505043639-c605e284fe17/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/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +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.1.1-0.20190913103102-20428fa0bffc/go.mod h1:ikMPikHu8SMvBGWoKulvvOOZN227amf2E9eMYqyAwAY= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +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.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +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-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 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.0.9-0.20191208103036-42f6e295b56f h1:i2BUTcG1g7lSgF/xVL4BJBAdrtNp4zL8woVTGHpEG4g= github.com/prometheus/procfs v0.0.9-0.20191208103036-42f6e295b56f/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/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/prometheus v2.5.0+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/statik v0.1.6/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563 h1:dY6ETXrvDG7Sa4vE8ZQG4yqWg6UnOcbqTAahkV813vQ= github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/reviewdog/errorformat v0.0.0-20200109134752-8983be9bc7dd/go.mod h1:giYAXnpegRDPsXUO7TRpDKXJo1lFGYxyWRfEt5iQ+OA= github.com/reviewdog/reviewdog v0.9.17/go.mod h1:Y0yPFDTi9L5ohkoecJdgbvAhq+dUXp+zI7atqVibwKg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= +github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8= github.com/samuel/go-parser v0.0.0-20130731160455-ca8abbf65d0e/go.mod h1:Sb6li54lXV0yYEjI4wX8cucdQ9gqUJV3+Ngg3l9g30I= github.com/samuel/go-thrift v0.0.0-20140522043831-2187045faa54/go.mod h1:Vrkh1pnjV9Bl8c3P9zH0/D4NlOHWP5d4/hF4YTULaec= github.com/sanathkr/go-yaml v0.0.0-20170819195128-ed9d249f429b/go.mod h1:8458kAagoME2+LN5//WxE71ysZ3B7r22fdgb7qVmXSY= github.com/sanathkr/yaml v0.0.0-20170819201035-0056894fa522/go.mod h1:tQTYKOQgxoH3v6dEmdHiz4JG+nbxWwM5fgPQUpSZqVQ= github.com/sanathkr/yaml v1.0.1-0.20170819201035-0056894fa522/go.mod h1:tQTYKOQgxoH3v6dEmdHiz4JG+nbxWwM5fgPQUpSZqVQ= +github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis= +github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shirou/gopsutil v2.19.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil v3.20.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= 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 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= 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= @@ -576,58 +1244,112 @@ github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIK github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/snowzach/rotatefilehook v0.0.0-20180327172521-2f64f265f58c h1:iUEy7/LRto3JqR/GLXDTEFP+s+qIjWw4pM8yzMfXC9A= github.com/snowzach/rotatefilehook v0.0.0-20180327172521-2f64f265f58c/go.mod h1:ZLVe3VfhAuMYLYWliGEydMBoRnfib8EFSqkBYu1ck9E= +github.com/snowzach/rotatefilehook v0.0.0-20220211133110-53752135082d h1:4660u5vJtsyrn3QwJNfESwCws+TM1CMhRn123xjVyQ8= +github.com/snowzach/rotatefilehook v0.0.0-20220211133110-53752135082d/go.mod h1:ZLVe3VfhAuMYLYWliGEydMBoRnfib8EFSqkBYu1ck9E= 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/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.3.0 h1:Ysnmjh1Di8EaWaBv40CYR4IdaIsBc5996Gh1oZzCBKk= github.com/spf13/afero v1.3.0/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= +github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= 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 v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= +github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= 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 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= +github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +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.1.2-0.20180702103455-b8b73a35e983 h1:4s04gnPlcop3dmAHjOAHWa6gX7Dg7h0gh81gr3GwzIk= github.com/stretchr/objx v0.1.2-0.20180702103455-b8b73a35e983/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/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.5.0/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 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/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= +github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs= +github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= 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/tidwall/gjson v1.6.7 h1:Mb1M9HZCRWEcXQ8ieJo7auYyyiSux6w9XN3AdTpxJrE= github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= github.com/tidwall/gjson v1.6.8 h1:CTmXMClGYPAmln7652e69B7OLXfTi5ABcPPwjIWUv7w= github.com/tidwall/gjson v1.6.8/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= +github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= +github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE= github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU= github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +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/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80/go.mod h1:iFyPdL66DjUD96XmzVL3ZntbzcflLnznH0fr99w5VqE= github.com/tsg/go-daemon v0.0.0-20200207173439-e704b93fd89b/go.mod h1:jAqhj/JBVC1PwcLTWd6rjQyGyItxxrhpiBl8LSuAGmw= github.com/tsg/gopacket v0.0.0-20190320122513-dd3d0e41124a h1:vVmCas8T0lbxAI1GuQO45L0o/OrWJSXtiK6vH27Qspg= github.com/tsg/gopacket v0.0.0-20190320122513-dd3d0e41124a/go.mod h1:RIkfovP3Y7my19aXEjjbNd9E5TlHozzAyt7B8AaEcwg= +github.com/tsg/gopacket v0.0.0-20200626092518-2ab8e397a786/go.mod h1:RIkfovP3Y7my19aXEjjbNd9E5TlHozzAyt7B8AaEcwg= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.8/go.mod h1:0lNM99SwWUIRhCXnigEMClngXBk/EmpTXa7mgiewYWA= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.8/go.mod h1:X00B19HDtwvKbQY2DcYjvZxKQp8mzrJoQ6EgoIY/D2E= 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/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urso/diag v0.0.0-20200210123136-21b3cc8eb797/go.mod h1:pNWFTeQ+V1OYT/TzWpnWb6eQBdoXpdx+H+lrH97/Oyo= github.com/urso/go-bin v0.0.0-20180220135811-781c575c9f0e h1:NiofbjIUI5gR+ybDsGSVH1fWyjSeDYiYVJHT1+kcsak= github.com/urso/go-bin v0.0.0-20180220135811-781c575c9f0e/go.mod h1:6GfHrdWBQYjFRIznu7XuQH4lYB2w8nO4bnImVKkzPOM= github.com/urso/magetools v0.0.0-20190919040553-290c89e0c230/go.mod h1:DFxTNgS/ExCGmmjVjSOgS2WjtfjKXgCyDzAFgbtovSA= @@ -635,11 +1357,22 @@ github.com/urso/magetools v0.0.0-20200106130147-61080ed7b22b h1:eRYRTx+2CteM4P2U github.com/urso/magetools v0.0.0-20200106130147-61080ed7b22b/go.mod h1:DFxTNgS/ExCGmmjVjSOgS2WjtfjKXgCyDzAFgbtovSA= github.com/urso/qcgen v0.0.0-20180131103024-0b059e7db4f4 h1:hhA8EBThzz9PztawVTycKvfETVuBqxAQ5keFlAVtbAw= github.com/urso/qcgen v0.0.0-20180131103024-0b059e7db4f4/go.mod h1:RspW+E2Yb7Fs7HclB2tiDaiu6Rp41BiIG4Wo1YaoXGc= +github.com/urso/sderr v0.0.0-20210525210834-52b04e8f5c71/go.mod h1:Wp40HwmjM59FkDIVFfcCb9LzBbnc0XAMp8++hJuWvSU= github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g= +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/vmware/govmomi v0.0.0-20170802214208-2cad15190b41/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= +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/xanzy/go-gitlab v0.22.3/go.mod h1:t4Bmvnxj7k37S4Y17lfLx+nLqkf/oQwT2HagfWKv5Og= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/scram v1.0.3/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xdg/stringprep v1.0.3/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= @@ -647,39 +1380,116 @@ github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf github.com/xeipuuv/gojsonschema v0.0.0-20181112162635-ac52e6811b56/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.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/gopher-lua v0.0.0-20170403160031-b402f3114ec7/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU= +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.elastic.co/apm v1.7.2/go.mod h1:tCw6CkOJgkWnzEthFN9HUP1uL3Gjc/Ur6m7gRPLaoH0= +go.elastic.co/apm v1.11.0/go.mod h1:qoOSi09pnzJDh5fKnfY7bPmQgl8yl2tULdOu03xhui0= +go.elastic.co/apm v1.15.0 h1:uPk2g/whK7c7XiZyz/YCUnAUBNPiyNeE3ARX3G6Gx7Q= +go.elastic.co/apm v1.15.0/go.mod h1:dylGv2HKR0tiCV+wliJz1KHtDyuD8SPe69oV7VyK6WY= +go.elastic.co/apm/module/apmelasticsearch v1.7.2/go.mod h1:ZyNFuyWdt42GBZkz0SogoLzDBrBGj4orxpiUuxYeYq8= +go.elastic.co/apm/module/apmhttp v1.7.2/go.mod h1:sTFWiWejnhSdZv6+dMgxGec2Nxe/ZKfHfz/xtRM+cRY= +go.elastic.co/ecszap v0.3.0/go.mod h1:HTUi+QRmr3EuZMqxPX+5fyOdMNfUu5iPebgfhgsTJYQ= +go.elastic.co/ecszap v1.0.1 h1:mBxqEJAEXBlpi5+scXdzL7LTFGogbuxipJC0KTZicyA= +go.elastic.co/ecszap v1.0.1/go.mod h1:SVjazT+QgNeHSGOCUHvRgN+ZRj5FkB7IXQQsncdF57A= +go.elastic.co/fastjson v1.0.0/go.mod h1:PmeUOMMtLHQr9ZS9J9owrAVg0FkaZDRZJEFTTGHtchs= +go.elastic.co/fastjson v1.1.0 h1:3MrGBWWVIxe/xvsbpghtkFoPciPhOCmjsR/HfwEeQR4= +go.elastic.co/fastjson v1.1.0/go.mod h1:boNGISWMjQsUPy/t6yqt2/1Wx4YNPSe+mZjlyw9vKKI= +go.elastic.co/go-licence-detector v0.4.0/go.mod h1:fSJQU8au4SAgDK+UQFbgUPsXKYNBDv4E/dwWevrMpXU= 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/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= +go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= +go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU= +go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= +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/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.1/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.1-0.20170829224307-fb7d312c2c04 h1:8sYuFs2lovgFwQi15/wIkCkGX9sL8RouzbWUmBjTcXk= go.uber.org/multierr v1.1.1-0.20170829224307-fb7d312c2c04/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.7.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= 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-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/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-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= 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-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +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-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= 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-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -690,15 +1500,35 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl 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/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 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/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -713,7 +1543,12 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn 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-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -722,8 +1557,55 @@ golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLL 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-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-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-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -732,6 +1614,21 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= 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= @@ -739,7 +1636,16 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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= @@ -747,8 +1653,10 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/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-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/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-20190222072716-a9d3bda3a223/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-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -757,30 +1665,160 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-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-20190529164535-6a60838ec259/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-20190813064441-fde4db37ae7a/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-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/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-20200102141924-c96a22e43c9c/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-20200116001909-b77594299b42/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 h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/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-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/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-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-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-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/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-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +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 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -795,26 +1833,120 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/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-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +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-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4 h1:Toz2IK7k8rbltAXwNAxKcn9OzqyNfMUhUNjz3sL0NMk= 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-20200216192241-b320d3a0f5a2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= 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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +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.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= +google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.81.0/go.mod h1:FA6Mb/bZxj706H2j+j2d6mHEEaHBmbbWnkfvmorOCko= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -823,45 +1955,185 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/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-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb h1:ADPHZzpzM4tk4V4S5cnCrr5SwzvlrPRmqqCuJDB8UTs= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211019152133-63b7e35f4404/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220426171045-31bebdecfb46/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220714211235-042d03aeabc9 h1:zfXhTgBfGlIh3jMXN06W8qbhFGsh6MJNJiYEuhTddOI= +google.golang.org/genproto v0.0.0-20220714211235-042d03aeabc9/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +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.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 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-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +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 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= 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/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= +gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= +gopkg.in/hjson/hjson-go.v3 v3.0.1/go.mod h1:X6zrTSVeImfwfZLfgQdInl9mWjqPqgH90jom9nym/lw= gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww= gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= +gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw= gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM= @@ -877,48 +2149,104 @@ gopkg.in/mgo.v2 v2.0.0-20160818020120-3f83fa500528/go.mod h1:yeKp02qBN3iKW1OzL3M gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= 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 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7/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 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c h1:grhR+C34yXImVGp7EzNk+DTIk+323eIUWOmEevy6bDo= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/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/gotestsum v0.6.0/go.mod h1:LEX+ioCVdeWhZc8GYfiBRag360eBhwixWJ62R9eDQtI= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +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= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= +howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= +howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= k8s.io/api v0.17.0 h1:H9d/lw+VkZKEVIUc8F3wgiQ+FUXTTr21M87jXLU7yqM= k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI= k8s.io/apimachinery v0.17.0 h1:xRBnuie9rXcPxUkDizUsGvPf1cnlZCFu210op7J7LJo= k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= +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.17.0 h1:8QOGvUGdqDMFrm9sD6IUFl256BcffynGoe80sxgTEDg= k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k= +k8s.io/code-generator v0.27.3/go.mod h1:DPung1sI5vBgn4AGKtlPRQAyagj/ir/4jI55ipZHVww= +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-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20220902162205-c0856e24416d/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.4-0.20190719014911-6a023d6d0e09/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= +k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= +k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= +k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20190712204705-3dccf664f023/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo= k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +kernel.org/pub/linux/libs/security/libcap/cap v1.2.57/go.mod h1:uI99C3r4SXvJeuqoEtx/eWt7UbmfqqZ80H8q+9t/A7I= +kernel.org/pub/linux/libs/security/libcap/psx v1.2.57/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 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/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= +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/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.1.1-0.20190704183835-4cd0c284b15f h1:rBmJnclilUaQG3K5/iL9zD57jtKRimbK2bJQGqktcs8= sigs.k8s.io/yaml v1.1.1-0.20190704183835-4cd0c284b15f/go.mod h1:JLeFbgenPHTQHNZeYbMLTT18IylpsFnR2+IHPl6wctA= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/pkg/gateway/cache.go b/pkg/gateway/cache.go deleted file mode 100644 index 9b546a0..0000000 --- a/pkg/gateway/cache.go +++ /dev/null @@ -1,53 +0,0 @@ -package gateway - -import ( - "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" - "github.com/Axway/agent-sdk/pkg/cache" -) - -// If the item is cached, return true -func setCachedService(kongServiceId string, kongServiceName string, hash string, centralName string) bool { - specCache := cache.GetCache() - item, err := specCache.Get(kongServiceId) - // if there is an error, then the item is not in the cache - if err != nil { - cachedService := CachedService{ - kongServiceId: kongServiceId, - kongServiceName: kongServiceName, - hash: hash, - centralName: centralName, - } - specCache.Set(kongServiceId, cachedService) - return false - } - - if item != nil { - if cachedService, ok := item.(CachedService); ok { - if cachedService.kongServiceId == kongServiceId && cachedService.hash == hash { - cachedService.centralName = centralName - cachedService.kongServiceName = kongServiceName - specCache.Set(kongServiceId, cachedService) - return true - } else { - cachedService.kongServiceName = kongServiceName - cachedService.hash = hash - specCache.Set(kongServiceId, cachedService) - } - } - } - return false -} - -func initCache(centralAPIServices []*v1alpha1.APIService) { - clearCache() - for _, apiSvc := range centralAPIServices { - setCachedService(apiSvc.Attributes[kongServiceID], apiSvc.Title, apiSvc.Attributes[kongHash], apiSvc.Name) - } -} - -func clearCache() { - cache := cache.GetCache() - for _, key := range cache.GetKeys() { - cache.Delete(key) - } -} diff --git a/pkg/gateway/centralclient.go b/pkg/gateway/centralclient.go index d5f05a7..ec68625 100644 --- a/pkg/gateway/centralclient.go +++ b/pkg/gateway/centralclient.go @@ -1,13 +1,7 @@ package gateway import ( - "encoding/json" - "fmt" - "net/http" - - "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" corecfg "github.com/Axway/agent-sdk/pkg/config" - "github.com/Axway/agent-sdk/pkg/util/log" ) type CentralAPIClient interface { @@ -32,25 +26,3 @@ func (cc *CentralClient) execute(method, endpoint string, queryParam map[string] host := cc.apiServerHost + cc.envName + endpoint return cc.client.ExecuteAPI(method, host, queryParam, buffer) } - -func (cc *CentralClient) fetchCentralAPIServices(queryParam map[string]string) ([]*v1alpha1.APIService, error) { - data, err := cc.execute(http.MethodGet, "/apiservices", queryParam, nil) - if err != nil { - return nil, fmt.Errorf("failed to get apiservices: %s", err) - } - - var centralAPIServices []*v1alpha1.APIService - err = json.Unmarshal(data, ¢ralAPIServices) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal apiservices: %s", err) - } - return centralAPIServices, nil -} - -func (cc *CentralClient) deleteCentralAPIService(cachedService CachedService) error { - // TODO: ExecuteAPI only returns a success when status code is 200 - cc.execute(http.MethodDelete, "/apiservices/"+cachedService.centralName, nil, nil) - - log.Infof("service removed: %s", cachedService.kongServiceName) - return nil -} diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 3fb75d7..ca7b35a 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -10,13 +10,8 @@ import ( "github.com/Axway/agents-kong/pkg/kong/specmanager/devportal" "github.com/Axway/agents-kong/pkg/kong/specmanager/localdir" - "github.com/sirupsen/logrus" - "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/apic" - "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" - "github.com/Axway/agent-sdk/pkg/cache" - "github.com/Axway/agent-sdk/pkg/util" "github.com/Axway/agent-sdk/pkg/util/log" config "github.com/Axway/agents-kong/pkg/config/discovery" @@ -47,27 +42,21 @@ func NewClient(agentConfig config.AgentConfig) (*Client, error) { specmanager.AddSource(localdir.NewSpecificationSource(agentConfig.KongGatewayCfg.SpecHomePath)) } - sm, err := initSubscriptionManager(kongClient.Client) - if err != nil { - return nil, err - } + //sm, err := initSubscriptionManager(kongClient.Client) + //if err != nil { + // return nil, err + //} return &Client{ - centralCfg: agentConfig.CentralCfg, - kongGatewayCfg: kongGatewayConfig, - kongClient: kongClient, - apicClient: apicClient, - subscriptionManager: sm, + centralCfg: agentConfig.CentralCfg, + kongGatewayCfg: kongGatewayConfig, + kongClient: kongClient, + apicClient: apicClient, + //subscriptionManager: sm, }, nil } func (gc *Client) DiscoverAPIs() error { - apiServices, err := gc.apicClient.fetchCentralAPIServices(nil) - if err != nil { - log.Infof("failed to get central api services: %s", err) - } - // TODO: initCache should only run once - initCache(apiServices) plugins := kutil.Plugins{PluginLister: gc.kongClient.GetKongPlugins()} gc.plugins = plugins services, err := gc.kongClient.ListServices(context.Background()) @@ -75,36 +64,10 @@ func (gc *Client) DiscoverAPIs() error { log.Errorf("failed to get services: %s", err) return err } - - gc.removeDeletedServices(services) gc.processKongServicesList(services) return nil } -func (gc *Client) removeDeletedServices(services []*klib.Service) { - specCache := cache.GetCache() - log.Info("checking for deleted kong services") - // TODO: add go funcs - for _, serviceID := range specCache.GetKeys() { - if !doesServiceExists(serviceID, services) { - item, err := specCache.Get(serviceID) - if err != nil { - log.Errorf("failed to get cached service: %s", serviceID) - } - cachedService := item.(CachedService) - err = gc.apicClient.deleteCentralAPIService(cachedService) - if err != nil { - log.Errorf("failed to delete service '%s': %s", cachedService.kongServiceName, err) - continue - } - err = specCache.Delete(serviceID) - if err != nil { - log.Errorf("failed to delete service '%s' from the cache: %s", cachedService.kongServiceName, err) - } - } - } -} - func (gc *Client) processKongServicesList(services []*klib.Service) { wg := new(sync.WaitGroup) @@ -134,18 +97,18 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se return err } if len(routes) == 0 { - gc.deleteCentralService(*service.ID, *service.Name) + // gc.deleteCentralService(*service.ID, *service.Name) return nil } route := routes[0] - ep, err := gc.plugins.GetEffectivePlugins(*route.ID, *service.ID) + _, err = gc.plugins.GetEffectivePlugins(*route.ID, *service.ID) if err != nil { return fmt.Errorf("failed to get plugins for route %s: %w", *route.ID, err) } - subscriptionInfo := gc.subscriptionManager.GetSubscriptionInfo(ep) + // subscriptionInfo := gc.subscriptionManager.GetSubscriptionInfo(ep) kongServiceSpec, err := specmanager.GetSpecification(ctx, service) if err != nil { @@ -157,8 +120,11 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se } endpoints := gc.processKongRoute(proxyEndpoint, oasSpec.BasePath(), route, httpPort, httpsPort) + subscriptionInfo := subscription.Info{} serviceBody, err := gc.processKongAPI(*route.ID, service, oasSpec, endpoints, subscriptionInfo) + //serviceBody, err := gc.processKongAPI(*route.ID, service, oasSpec, endpoints, subscriptionInfo) + if err != nil { return err } @@ -177,25 +143,25 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se return nil } -func (gc *Client) deleteCentralService(serviceID string, serviceName string) { - log.Debugf("kong service '%s' has no routes.", serviceName) - item, _ := cache.GetCache().Get(serviceID) - - if svc, ok := item.(CachedService); ok { - err := gc.apicClient.deleteCentralAPIService(svc) - - if err != nil { - log.Errorf("failed to delete service '%' from central: %s", err) - } else { - log.Warnf("deleted Kong service '%s' from central", serviceName) - } - - cache.GetCache().Delete(serviceID) - } -} - -func (gc *Client) processKongRoute(defaultHost string, basePath string, route *klib.Route, httpPort, httpsPort int) []InstanceEndpoint { - var endpoints []InstanceEndpoint +//func (gc *Client) deleteCentralService(serviceID string, serviceName string) { +// log.Debugf("kong service '%s' has no routes.", serviceName) +// item, _ := cache.GetCache().Get(serviceID) +// +// if svc, ok := item.(CachedService); ok { +// err := gc.apicClient.deleteCentralAPIService(svc) +// +// if err != nil { +// log.Errorf("failed to delete service '%' from central: %s", err) +// } else { +// log.Warnf("deleted Kong service '%s' from central", serviceName) +// } +// +// cache.GetCache().Delete(serviceID) +// } +//} + +func (gc *Client) processKongRoute(defaultHost string, basePath string, route *klib.Route, httpPort, httpsPort int) []apic.EndpointDefinition { + var endpoints []apic.EndpointDefinition if route == nil { return endpoints } @@ -215,11 +181,11 @@ func (gc *Client) processKongRoute(defaultHost string, basePath string, route *k if *route.StripPath == true { routingBasePath = routingBasePath + basePath } - endpoint := InstanceEndpoint{ + endpoint := apic.EndpointDefinition{ Host: *host, Port: int32(port), Protocol: *protocol, - Routing: v1alpha1.ApiServiceInstanceSpecRouting{BasePath: routingBasePath}, + BasePath: routingBasePath, } endpoints = append(endpoints, endpoint) } @@ -233,10 +199,10 @@ func (gc *Client) processKongAPI( routeID string, service *klib.Service, oasSpec Openapi, - endpoints []InstanceEndpoint, + endpoints []apic.EndpointDefinition, subscriptionInfo subscription.Info, ) (*apic.ServiceBody, error) { - name := gc.centralCfg.GetEnvironmentName() + "." + *service.Name + name := *service.Name kongAPI := newKongAPI(routeID, service, oasSpec, endpoints, name, subscriptionInfo) serviceBody, err := kongAPI.buildServiceBody() @@ -249,10 +215,10 @@ func (gc *Client) processKongAPI( serviceBody.ServiceAttributes[kongHash] = hash serviceBody.ServiceAttributes[kongServiceID] = *service.ID - isCached := setCachedService(*service.ID, *service.Name, hash, serviceBody.APIName) - if isCached { - return nil, nil - } + //isCached := setCachedService(*service.ID, *service.Name, hash, serviceBody.APIName) + //if isCached { + // return nil, nil + //} return &serviceBody, nil } @@ -261,22 +227,22 @@ func newKongAPI( routeID string, service *klib.Service, oasSpec Openapi, - endpoints []InstanceEndpoint, + endpoints []apic.EndpointDefinition, nameToPush string, info subscription.Info, ) KongAPI { return KongAPI{ - id: routeID, - name: *service.Name, - description: oasSpec.Description(), - version: oasSpec.Version(), - url: *service.Host, - resourceType: oasSpec.ResourceType(), - documentation: []byte("\"Sample documentation for API discovery agent\""), - swaggerSpec: []byte(oasSpec.spec), - endpoints: endpoints, - nameToPush: nameToPush, - subscriptionInfo: info, + id: routeID, + name: *service.Name, + description: oasSpec.Description(), + version: oasSpec.Version(), + url: *service.Host, + resourceType: oasSpec.ResourceType(), + documentation: []byte("\"Sample documentation for API discovery agent\""), + swaggerSpec: []byte(oasSpec.spec), + endpoints: endpoints, + nameToPush: nameToPush, + //subscriptionInfo: info, } } @@ -294,11 +260,7 @@ func (ka *KongAPI) buildServiceBody() (apic.ServiceBody, error) { SetURL(ka.url). SetVersion(ka.version). SetAuthPolicy(ka.subscriptionInfo.APICPolicyName). - SetSubscriptionName(ka.subscriptionInfo.SchemaName) - - for _, ep := range ka.endpoints { - body.AddServiceEndpoint(ep.Protocol, ep.Host, ep.Port, ep.Routing.BasePath) - } + SetSubscriptionName(ka.subscriptionInfo.SchemaName).SetServiceEndpoints(ka.endpoints) sb, err := body.Build() @@ -310,39 +272,39 @@ func (ka *KongAPI) buildServiceBody() (apic.ServiceBody, error) { return sb, err } -func doesServiceExists(serviceId string, services []*klib.Service) bool { - for _, srv := range services { - if serviceId == *srv.ID { - return true - } - } - log.Infof("Kong service '%s' no longer exists.", serviceId) - - return false -} - -func initSubscriptionManager(kc *klib.Client) (*subscription.Manager, error) { - sm := subscription.New( - logrus.StandardLogger(), - agent.GetCentralClient(), - agent.GetCentralClient(), - kc) - - // register schemas - for _, schema := range sm.Schemas() { - if err := agent.GetCentralClient().RegisterSubscriptionSchema(schema); err != nil { - return nil, fmt.Errorf("failed to register subscription schema %s: %w", schema.GetSubscriptionName(), err) - } - log.Infof("Schema registered: %s", schema.GetSubscriptionName()) - } - - agent.GetCentralClient().GetSubscriptionManager().RegisterValidator(sm.ValidateSubscription) - // register validator and handlers - agent.GetCentralClient().GetSubscriptionManager().RegisterProcessor(apic.SubscriptionApproved, sm.ProcessSubscribe) - agent.GetCentralClient().GetSubscriptionManager().RegisterProcessor(apic.SubscriptionUnsubscribeInitiated, sm.ProcessUnsubscribe) - - // start polling for subscriptions - agent.GetCentralClient().GetSubscriptionManager().Start() - - return sm, nil -} +//func doesServiceExists(serviceId string, services []*klib.Service) bool { +// for _, srv := range services { +// if serviceId == *srv.ID { +// return true +// } +// } +// log.Infof("Kong service '%s' no longer exists.", serviceId) +// +// return false +//} + +//func initSubscriptionManager(kc *klib.Client) (*subscription.Manager, error) { +// sm := subscription.New( +// logrus.StandardLogger(), +// agent.GetCentralClient(), +// agent.GetCentralClient(), +// kc) +// +// // register schemas +// for _, schema := range sm.Schemas() { +// if err := agent.GetCentralClient().RegisterSubscriptionSchema(schema); err != nil { +// return nil, fmt.Errorf("failed to register subscription schema %s: %w", schema.GetSubscriptionName(), err) +// } +// log.Infof("Schema registered: %s", schema.GetSubscriptionName()) +// } +// +// agent.GetCentralClient().GetSubscriptionManager().RegisterValidator(sm.ValidateSubscription) +// // register validator and handlers +// agent.GetCentralClient().GetSubscriptionManager().RegisterProcessor(apic.SubscriptionApproved, sm.ProcessSubscribe) +// agent.GetCentralClient().GetSubscriptionManager().RegisterProcessor(apic.SubscriptionUnsubscribeInitiated, sm.ProcessUnsubscribe) +// +// // start polling for subscriptions +// agent.GetCentralClient().GetSubscriptionManager().Start() +// +// return sm, nil +//} diff --git a/pkg/gateway/definitions.go b/pkg/gateway/definitions.go index 16130e4..88e003f 100644 --- a/pkg/gateway/definitions.go +++ b/pkg/gateway/definitions.go @@ -1,17 +1,15 @@ package gateway import ( + "github.com/Axway/agent-sdk/pkg/apic" "github.com/Axway/agents-kong/pkg/kong" "github.com/Axway/agents-kong/pkg/subscription" - "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" corecfg "github.com/Axway/agent-sdk/pkg/config" config "github.com/Axway/agents-kong/pkg/config/discovery" kutil "github.com/Axway/agents-kong/pkg/kong" ) -type InstanceEndpoint = v1alpha1.ApiServiceInstanceSpecEndpoint - type Client struct { centralCfg corecfg.CentralConfig kongGatewayCfg *config.KongGatewayConfig @@ -30,7 +28,7 @@ type KongAPI struct { url string documentation []byte resourceType string - endpoints []InstanceEndpoint + endpoints []apic.EndpointDefinition subscriptionInfo subscription.Info nameToPush string } diff --git a/pkg/kong/kongclient.go b/pkg/kong/kongclient.go index 51ac33d..fa44d4e 100644 --- a/pkg/kong/kongclient.go +++ b/pkg/kong/kongclient.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "github.com/Axway/agents-kong/pkg/kong/specmanager" @@ -35,7 +35,7 @@ func NewKongClient(baseClient *http.Client, kongConfig *config.KongGatewayConfig headers := make(http.Header) headers.Set("Kong-Admin-Token", kongConfig.Token) client := klib.HTTPClientWithHeaders(baseClient, headers) - baseClient = &client + baseClient = client } baseKongClient, err := klib.NewClient(&kongConfig.AdminEndpoint, baseClient) @@ -68,7 +68,7 @@ func (k KongClient) GetSpecForService(ctx context.Context, serviceId string) (*s if err != nil { return nil, fmt.Errorf("failed to execute request: %s", err) } - data, err := ioutil.ReadAll(res.Body) + data, err := io.ReadAll(res.Body) if err != nil { return nil, fmt.Errorf("failed to read body: %s", err) } @@ -95,7 +95,7 @@ func (k KongClient) getSpec(ctx context.Context, path string) (*specmanager.Kong return nil, fmt.Errorf("failed to execute request: %s", err) } - data, err := ioutil.ReadAll(res.Body) + data, err := io.ReadAll(res.Body) if err != nil { return nil, fmt.Errorf("failed to read body: %s", err) } diff --git a/pkg/subscription/subscriptionmanager.go b/pkg/subscription/subscriptionmanager.go index d1573a0..0f21c84 100644 --- a/pkg/subscription/subscriptionmanager.go +++ b/pkg/subscription/subscriptionmanager.go @@ -17,7 +17,7 @@ func Register(constructor func(*kong.Client) Handler) { // ConsumerInstanceGetter gets a consumer instance by id. type ConsumerInstanceGetter interface { - GetConsumerInstanceByID(id string) (*v1alpha1.ConsumerInstance, error) + GetConsumerInstanceByID(id string) (*management.ConsumerInstance, error) } // SubscriptionGetter gets the all the subscription in any of the states for the catalog item with id From eaf7fe2c325fbedc201b961b9f7b78891d955467 Mon Sep 17 00:00:00 2001 From: rathnapandi Date: Fri, 4 Aug 2023 20:11:28 -0700 Subject: [PATCH 36/76] - apikey marketplace provisioning in progress --- docker-compose.yml | 7 +- go.mod | 88 +- go.sum | 1406 ++--------------------- pkg/common/common.go | 8 + pkg/gateway/client.go | 2 +- pkg/subscription/apikey.go | 12 - pkg/subscription/apikey/apikey.go | 206 ---- pkg/subscription/auth/apikey.go | 137 +++ pkg/subscription/auth/basicauth.go | 1 + pkg/subscription/auth/jwt.go | 1 + pkg/subscription/auth/oauth2.go | 1 + pkg/subscription/package.go | 3 - pkg/subscription/provision.go | 264 +++++ pkg/subscription/subscription_test.go | 427 ------- pkg/subscription/subscriptionmanager.go | 221 ---- 15 files changed, 579 insertions(+), 2205 deletions(-) create mode 100644 pkg/common/common.go delete mode 100644 pkg/subscription/apikey.go delete mode 100644 pkg/subscription/apikey/apikey.go create mode 100644 pkg/subscription/auth/apikey.go create mode 100644 pkg/subscription/auth/basicauth.go create mode 100644 pkg/subscription/auth/jwt.go create mode 100644 pkg/subscription/auth/oauth2.go delete mode 100644 pkg/subscription/package.go create mode 100644 pkg/subscription/provision.go delete mode 100644 pkg/subscription/subscription_test.go delete mode 100644 pkg/subscription/subscriptionmanager.go diff --git a/docker-compose.yml b/docker-compose.yml index a1a3dc7..9f18ed1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.7' services: kong-db: - image: postgres:13 + image: postgres:11 environment: POSTGRES_USER: kong POSTGRES_DB: kong @@ -12,7 +12,8 @@ services: ports: - "5432:5432" kong-migration: - image: kong:3.3.1 +# image: kong:3.3.1 + image: kong:2.8.3 command: kong migrations bootstrap environment: KONG_ADMIN_ACCESS_LOG: /dev/stdout @@ -31,7 +32,7 @@ services: depends_on: - kong-db kong: - image: kong:3.3.1 + image: kong:2.8.3 environment: KONG_ADMIN_ACCESS_LOG: /dev/stdout KONG_ADMIN_ERROR_LOG: /dev/stderr diff --git a/go.mod b/go.mod index 1357ddb..363e647 100644 --- a/go.mod +++ b/go.mod @@ -9,51 +9,84 @@ require ( github.com/kong/go-kong v0.46.0 github.com/sirupsen/logrus v1.9.3 github.com/tidwall/gjson v1.14.4 + gotest.tools v2.2.0+incompatible ) require ( - 4d63.com/tz v1.1.1-0.20191124060701-6d37baae851b // indirect + github.com/Microsoft/go-winio v0.5.1 // indirect github.com/Shopify/sarama v1.26.4 // indirect + github.com/StackExchange/wmi v0.0.0-20170221213301-9f32b5905fd6 // indirect github.com/armon/go-radix v1.0.0 // indirect + github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect - github.com/dgrijalva/jwt-go v3.2.1-0.20190620180102-5e25c22bd5d6+incompatible // indirect + github.com/dlclark/regexp2 v1.1.7-0.20171009020623-7632a260cbaf // indirect + github.com/docker/distribution v2.8.0+incompatible // indirect github.com/docker/docker v1.13.1 // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.4.0 // indirect + github.com/dop251/goja v0.0.0-20200831102558-9af81ddcf0e1 // indirect + github.com/dop251/goja_nodejs v0.0.0-20171011081505-adff31b136e6 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/eapache/go-resiliency v1.2.0 // indirect + github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect + github.com/eapache/queue v1.1.0 // indirect + github.com/elastic/ecs v1.12.0 // indirect github.com/elastic/elastic-agent-client/v7 v7.0.0-20220607160924-1a71765a8bbe // indirect - github.com/elastic/go-libaudit v0.4.0 // indirect + github.com/elastic/go-concert v0.2.0 // indirect github.com/elastic/go-licenser v0.4.1 // indirect + github.com/elastic/go-lumber v0.1.0 // indirect + github.com/elastic/go-seccomp-bpf v1.2.0 // indirect + github.com/elastic/go-structform v0.0.9 // indirect github.com/elastic/go-sysinfo v1.8.1 // indirect + github.com/elastic/go-txfile v0.0.7 // indirect github.com/elastic/go-ucfg v0.8.6 // indirect github.com/elastic/go-windows v1.0.1 // indirect + github.com/elastic/gosigar v0.14.2 // indirect github.com/emicklei/proto v1.9.2 // indirect github.com/fatih/color v1.13.0 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/gabriel-vasile/mimetype v1.4.0 // indirect - github.com/garyburd/redigo v1.6.0 // indirect github.com/getkin/kin-openapi v0.76.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect + github.com/go-logr/logr v1.2.3 // indirect + github.com/go-ole/go-ole v1.2.5-0.20190920104607-14974a1cf647 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-sourcemap/sourcemap v2.1.2+incompatible // indirect github.com/goccy/go-json v0.10.2 // indirect + github.com/gofrs/flock v0.7.2-0.20190320160742-5135e617513b // indirect github.com/gofrs/uuid v4.2.0+incompatible // indirect + github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/gomodule/redigo v1.8.3 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-querystring v1.1.0 // indirect + github.com/google/gofuzz v1.1.0 // indirect + github.com/googleapis/gnostic v0.4.1 // indirect github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect + github.com/h2non/filetype v1.1.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-uuid v1.0.2 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jcchavezs/porto v0.4.0 // indirect + github.com/jcmturner/aescts/v2 v2.0.0 // indirect + github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect github.com/jcmturner/gofork v1.0.0 // indirect + github.com/jcmturner/gokrb5/v8 v8.4.2 // indirect + github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect - github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca // indirect + github.com/jonboulle/clockwork v0.2.2 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/cpuid v1.3.1 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.13.6 // indirect github.com/kong/semver/v4 v4.0.1 // indirect github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect github.com/lestrrat-go/blackmagic v1.0.1 // indirect @@ -66,14 +99,21 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect + github.com/miekg/dns v1.1.25 // indirect github.com/mitchellh/hashstructure v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.2 // indirect + github.com/pierrec/lz4 v2.6.0+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect - github.com/reviewdog/reviewdog v0.9.17 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect + github.com/shirou/gopsutil v3.20.12+incompatible // indirect github.com/snowzach/rotatefilehook v0.0.0-20220211133110-53752135082d // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect @@ -84,8 +124,15 @@ require ( github.com/subosito/gotenv v1.4.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect + github.com/urso/diag v0.0.0-20200210123136-21b3cc8eb797 // indirect + github.com/urso/go-bin v0.0.0-20180220135811-781c575c9f0e // indirect github.com/urso/magetools v0.0.0-20200106130147-61080ed7b22b // indirect + github.com/urso/sderr v0.0.0-20210525210834-52b04e8f5c71 // indirect + github.com/xdg/scram v1.0.3 // indirect + github.com/xdg/stringprep v1.0.3 // indirect go.elastic.co/apm v1.15.0 // indirect + go.elastic.co/apm/module/apmelasticsearch v1.7.2 // indirect + go.elastic.co/apm/module/apmhttp v1.7.2 // indirect go.elastic.co/ecszap v1.0.1 // indirect go.elastic.co/fastjson v1.1.0 // indirect go.uber.org/atomic v1.9.0 // indirect @@ -95,26 +142,43 @@ require ( golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect golang.org/x/mod v0.9.0 // indirect golang.org/x/net v0.10.0 // indirect + golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect golang.org/x/sys v0.9.0 // indirect + golang.org/x/term v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect + golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect golang.org/x/tools v0.7.0 // indirect + google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220714211235-042d03aeabc9 // indirect google.golang.org/grpc v1.48.0 // indirect google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.6 // indirect + gopkg.in/jcmturner/aescts.v1 v1.0.1 // indirect + gopkg.in/jcmturner/dnsutils.v1 v1.0.1 // indirect + gopkg.in/jcmturner/goidentity.v3 v3.0.0 // indirect gopkg.in/jcmturner/gokrb5.v7 v7.5.0 // indirect + gopkg.in/jcmturner/rpc.v1 v1.1.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect howett.net/plist v1.0.0 // indirect + k8s.io/api v0.21.1 // indirect + k8s.io/apimachinery v0.22.7 // indirect + k8s.io/client-go v0.21.1 // indirect + k8s.io/klog/v2 v2.90.1 // indirect + k8s.io/utils v0.0.0-20201110183641-67b214c5f920 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) replace ( - github.com/Shopify/sarama => github.com/elastic/sarama v0.0.0-20191122160421-355d120d0970 + github.com/Shopify/sarama => github.com/elastic/sarama v1.19.1-0.20210823122811-11c3ef800752 github.com/docker/docker => github.com/docker/engine v17.12.0-ce-rc1.0.20190717161051-705d9623b7c1+incompatible github.com/dop251/goja => github.com/andrewkroh/goja v0.0.0-20190128172624-dd2ac4456e20 - github.com/fsnotify/fsnotify => github.com/adriansr/fsnotify v0.0.0-20180417234312-c9bbe1f46f1d - k8s.io/api => k8s.io/api v0.17.0 - k8s.io/apimachinery => k8s.io/apimachinery v0.17.0 - k8s.io/client-go => k8s.io/client-go v0.17.0 + github.com/dop251/goja_nodejs => github.com/dop251/goja_nodejs v0.0.0-20171011081505-adff31b136e6 + github.com/getkin/kin-openapi => github.com/getkin/kin-openapi v0.67.0 + k8s.io/apimachinery => k8s.io/apimachinery v0.21.1 + k8s.io/client-go => k8s.io/client-go v0.21.1 + ) diff --git a/go.sum b/go.sum index d84b547..922f1e0 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,3 @@ -4d63.com/embedfiles v0.0.0-20190311033909-995e0740726f/go.mod h1:HxEsUxoVZyRxsZML/S6e2xAuieFMlGO0756ncWx1aXE= -4d63.com/tz v1.1.1-0.20191124060701-6d37baae851b/go.mod h1:SHGqVdL7hd2ZaX2T9uEiOZ/OFAUfCCLURdLPJsd8ZNs= -bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 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= @@ -10,7 +7,6 @@ cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxK 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.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= 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= @@ -21,474 +17,134 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= -cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= -cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= -cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= -cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= -cloud.google.com/go/kms v1.0.0/go.mod h1:nhUehi+w7zht2XrUfvTRNpxrfayBHqP4lu2NSywui/0= -cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/pubsub v1.17.1/go.mod h1:4qDxMr1WsM9+aQAz36ltDwCIM+R0QdlseyFjBuNvnss= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -code.cloudfoundry.org/go-diodes v0.0.0-20190809170250-f77fb823c7ee/go.mod h1:Jzi+ccHgo/V/PLQUaQ6hnZcC1c4BS790gx21LRRui4g= -code.cloudfoundry.org/go-loggregator v7.4.0+incompatible/go.mod h1:KPBTRqj+y738Nhf1+g4JHFaBU8j7dedirR5ETNHvMXU= -code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:sk5LnIjB/nIEU7yP5sDQExVm62wu0pBh3yrElngUisI= -code.cloudfoundry.org/rfc5424 v0.0.0-20180905210152-236a6d29298a/go.mod h1:tkZo8GtzBjySJ7USvxm4E36lNQw1D3xM6oKHGqdaAJ4= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Axway/agent-sdk v1.0.20210421 h1:sZBM0OPMlpRwkf1y6jRSEsEC3cFT5eds6hoE6usKvfE= -github.com/Axway/agent-sdk v1.0.20210421/go.mod h1:ESIGxeiVC5Cza+MYgj5yGePQNjkT8diz4HxkQBCHwFk= github.com/Axway/agent-sdk v1.1.58 h1:wnrnuRKus/aZPLhOPZr8FiCPbCQ4VJBra/Gp7iVFdbs= github.com/Axway/agent-sdk v1.1.58/go.mod h1:xe6dIpQxE0LcSR+ssGKL4mfyLFbrLohdrB9iMYFUCdU= -github.com/Azure/azure-amqp-common-go/v3 v3.0.0/go.mod h1:SY08giD/XbhTz07tJdpw1SoxQXHPN30+DI3Z04SYqyg= -github.com/Azure/azure-amqp-common-go/v3 v3.2.1/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI= -github.com/Azure/azure-event-hubs-go/v3 v3.1.2/go.mod h1:hR40byNJjKkS74+3RhloPQ8sJ8zFQeJ920Uk3oYY0+k= -github.com/Azure/azure-event-hubs-go/v3 v3.3.15/go.mod h1:xgDvUi1+8/bb11WTEaU7VwZREYufzKzjWE4YiPZixb0= -github.com/Azure/azure-pipeline-go v0.1.8/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg= -github.com/Azure/azure-pipeline-go v0.1.9/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg= -github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= -github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v37.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v51.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v59.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-storage-blob-go v0.6.0/go.mod h1:oGfmITT1V6x//CswqY2gtAHND+xIP64/qL7a5QJix0Y= -github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= -github.com/Azure/go-amqp v0.12.6/go.mod h1:qApuH6OFTSKZFmCOxccvAv5rLizBQf4v8pRmG138DPo= -github.com/Azure/go-amqp v0.16.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= -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.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= -github.com/Azure/go-autorest/autorest v0.9.4/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= -github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= -github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= -github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/adal v0.9.15/go.mod h1:tGMin8I49Yij6AQ+rvV+Xa/zwxYQB5hmsd6DkfAx2+A= -github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM= -github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw= -github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= +github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= -github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= -github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= -github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= -github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +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 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= 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/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Microsoft/go-winio v0.4.9/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -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 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA= -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/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= github.com/Microsoft/go-winio v0.5.1/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 v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= -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/PaesslerAG/gval v1.0.0/go.mod h1:y/nm5yEyTeX6av0OfKJNp9rBNj2XrGhAf5+v24IBN1I= -github.com/PaesslerAG/jsonpath v0.1.0/go.mod h1:4BzmtoM/PI8fPO4aQGIusjGxGir2BzcV0grWtFzq1Y8= -github.com/PaesslerAG/jsonpath v0.1.1/go.mod h1:lVboNxFGal/VwW6d9JzIy56bUsYAP6tH/x80vjnCseY= -github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= 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/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/StackExchange/wmi v0.0.0-20170221213301-9f32b5905fd6 h1:2Gl9Tray0NEjP9KC0FjdGWlszbmTIsBP3JYzgyFdL4E= github.com/StackExchange/wmi v0.0.0-20170221213301-9f32b5905fd6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/adriansr/fsnotify v0.0.0-20180417234312-c9bbe1f46f1d h1:g0M6kedfjDpyAAuxqBvJzMNjFzlrQ7Av6LCDFqWierk= -github.com/adriansr/fsnotify v0.0.0-20180417234312-c9bbe1f46f1d/go.mod h1:VykaKG/ofkKje+MSvqjrDsz1wfyHIvEVFljhq2EOZ4g= -github.com/adriansr/gopacket v1.1.18-0.20200327165309-dd62abfa8a41/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= -github.com/aerospike/aerospike-client-go v1.27.1-0.20170612174108-0f3b54da6bdc/go.mod h1:zj8LBEnWBDOVEIJt8LvaRvDG5ARAoa5dBeHaB472NRc= -github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= -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/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/andrewkroh/goja v0.0.0-20190128172624-dd2ac4456e20 h1:7rj9qZ63knnVo2ZeepYHvHuRdG76f3tRUTdIQDzRBeI= github.com/andrewkroh/goja v0.0.0-20190128172624-dd2ac4456e20/go.mod h1:cI59GRkC2FRaFYtgbYEqMlgnnfvAwXzjojyZKXwklNg= -github.com/andrewkroh/sys v0.0.0-20151128191922-287798fe3e43/go.mod h1:tJPYQG4mnMeUtQvQKNkbsFrnmZOg59Qnf8CcctFv5v4= -github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= +github.com/andrewkroh/sys v0.0.0-20151128191922-287798fe3e43 h1:WFwa9pqou0Nb4DdfBOyaBTH0GqLE74Qwdf61E7ITHwQ= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/antlr/antlr4 v0.0.0-20200820155224-be881fa6b91d/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y= -github.com/apache/thrift v0.13.1-0.20200603211036-eac4d0c79a5f/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apoydence/eachers v0.0.0-20181020210610-23942921fe77/go.mod h1:bXvGk6IkT1Agy7qzJ+DjIw/SJ1AaB3AvAuMDVV+Vkoo= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/aws/aws-lambda-go v1.6.0/go.mod h1:zUsUQhAUjYzR8AuduJPCfhBuKWUaDbQiPOG+ouzmE1A= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/aws/aws-sdk-go v1.19.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go-v2 v0.9.0/go.mod h1:sa1GePZ/LfBGI4dSq30f6uR4Tthll8axxtEPvlpXZ8U= -github.com/aws/aws-sdk-go-v2 v0.24.0/go.mod h1:2LhT7UgHOXK3UXONKI5OMgIyoQL6zTAw/jwIeX6yqzw= -github.com/awslabs/goformation/v3 v3.1.0/go.mod h1:hQ5RXo3GNm2laHWKizDzU5DsDy+yNcenSca2UxN0850= -github.com/awslabs/goformation/v4 v4.1.0/go.mod h1:MBDN7u1lMNDoehbFuO4uPvgwPeolTMA2TzX1yO6KlxI= -github.com/awslabs/kinesis-aggregation/go v0.0.0-20200810181507-d352038274c0/go.mod h1:SghidfnxvX7ribW6nHI7T+IBbc9puZ9kk5Tx/88h8P4= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -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/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= -github.com/blang/semver v0.0.0-20190414102917-ba2c2ddd8906/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blang/semver v3.1.0+incompatible h1:7hqmJYuaEK3qwVjWubYiht3j93YI0WQBuysxHIfUriU= -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/bradleyfalzon/ghinstallation v1.1.0/go.mod h1:p7iD8KytOOKg2wCqbwvJlq4JGpYMjwjkiqdyUqOIHLI= -github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= -github.com/bsm/sarama-cluster v2.1.14-0.20180625083203-7e67d87a6b3f+incompatible/go.mod h1:r7ao+4tTNXvWm+VRpRJchr2kQhqxgmAp2iEX5W96gMM= -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/cavaliercoder/badio v0.0.0-20160213150051-ce5280129e9e/go.mod h1:V284PjgVwSk4ETmz84rpu9ehpGg7swlIH8npP9k2bGw= -github.com/cavaliercoder/go-rpm v0.0.0-20190131055624-7a9c54e3d83e/go.mod h1:AZIh1CCnMrcVm6afFf96PBvE2MRpWFco91z8ObJtgDY= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= -github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= 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/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudfoundry-community/go-cfclient v0.0.0-20190808214049-35bcce23fc5f/go.mod h1:RtIewdO+K/czvxvIFCMbPyx7jdxSLL1RZ+DA/Vk8Lwg= -github.com/cloudfoundry/noaa v2.1.0+incompatible/go.mod h1:5LmacnptvxzrTvMfL9+EJhgkUfIgcwI61BVSTh47ECo= -github.com/cloudfoundry/sonde-go v0.0.0-20171206171820-b33733203bb4/go.mod h1:GS0pCHd7onIsewbw8Ue9qa9pZPv2V88cUZDttK6KzgI= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= -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/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/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.3.3/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/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= -github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= -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-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY= -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/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-20190816180239-bda0ff6ed73c/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/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/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/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/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.1-coreos.6.0.20180318001526-af9db2027c98/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -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/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -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/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/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 v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -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/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cucumber/godog v0.8.1/go.mod h1:vSh3r/lM+psC1BPXvdkSEuNjmXfpVqrMGYAElF6hxnA= -github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= -github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= -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 v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/davecgh/go-xdr v0.0.0-20161123171359-e6a2ba005892/go.mod h1:CTDl0pzVzE5DEzZhPfvhY/9sPFMQIxaJ9VAMs9AagrE= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= -github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc= -github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= -github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= -github.com/devigned/tab v0.1.2-0.20190607222403-0c15cf42f9a2/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= -github.com/dgraph-io/badger/v3 v3.2103.1/go.mod h1:dULbq6ehJ5K0cGW/1TQ9iSfUk0gbSiToDWmWmTsJ53E= -github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= -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/dgrijalva/jwt-go v3.2.1-0.20190620180102-5e25c22bd5d6+incompatible h1:4jGdduO4ceTJFKf0IhgaB8NJapGqKHwC2b4xQ/cXujM= -github.com/dgrijalva/jwt-go v3.2.1-0.20190620180102-5e25c22bd5d6+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/digitalocean/go-libvirt v0.0.0-20180301200012-6075ea3c39a1/go.mod h1:PRcPVAAma6zcLpFd4GZrjR/MRpood3TamjKI2m/z/Uw= -github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dlclark/regexp2 v1.1.7-0.20171009020623-7632a260cbaf h1:uOWCk+L8abzw0BzmnCn7j7VT3g6bv9zW8fkR0yOP0Q4= github.com/dlclark/regexp2 v1.1.7-0.20171009020623-7632a260cbaf/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -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 h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= -github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.8.0+incompatible h1:l9EaZDICImO1ngI+uTifW+ZYvvz7fKISBAKpg+MbWbY= github.com/docker/distribution v2.8.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/engine v17.12.0-ce-rc1.0.20190717161051-705d9623b7c1+incompatible h1:4Pnn+RsurVEiBbmqlRtzh77HLMiP4NaaqRHOOK4aPj8= github.com/docker/engine v17.12.0-ce-rc1.0.20190717161051-705d9623b7c1+incompatible/go.mod h1:3CPr2caMgTHxxIAZgEMd3uLYPDlRvPqCpyeRf6ncPcY= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -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-plugins-helpers v0.0.0-20181025120712-1e6269c305b8/go.mod h1:LFyLie6XcDbyKGeVK6bHe+9aJTYCxWLBg5IrJZOaXKA= -github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= 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/dolmen-go/contextio v0.0.0-20200217195037-68fc5150bcd5/go.mod h1:cxc20xI7fOgsFHWgt+PenlDDnMcrvh7Ocuj5hEFIdEk= github.com/dop251/goja_nodejs v0.0.0-20171011081505-adff31b136e6 h1:RrkoB0pT3gnjXhL/t10BSP1mcr/0Ldea2uMyuBr2SWk= github.com/dop251/goja_nodejs v0.0.0-20171011081505-adff31b136e6/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q= github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/eclipse/paho.mqtt.golang v1.2.1-0.20200121105743-0d940dd29fd2/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= -github.com/elastic/beats/v7 v7.7.1 h1:aets27tEojy9IbpCW/X3CxlzObVjtMKyLpGk9RtXYNM= -github.com/elastic/beats/v7 v7.7.1/go.mod h1:6wQ39q838+pC8Y927cbdfRWFnoOvni1+CTorV4lgpYA= github.com/elastic/beats/v7 v7.17.5 h1:/cvFiUuXnIHzBnb7RzCfn06nydYbJyD9VIPv2N4UWG4= github.com/elastic/beats/v7 v7.17.5/go.mod h1:nFsbsraCRGlck/aOwtfEJFKEyVBiDqxGvZ3ZES6sMn4= -github.com/elastic/dhcp v0.0.0-20200227161230-57ec251c7eb3/go.mod h1:aPqzac6AYkipvp4hufTyMj5PDIphF3+At8zr7r51xjY= -github.com/elastic/ecs v1.5.0 h1:/VEIBsRU4ecq2+U3RPfKNc6bFyomP6qnthYEcQZu8GU= -github.com/elastic/ecs v1.5.0/go.mod h1:pgiLbQsijLOJvFR8OTILLu0Ni/R/foUNg0L+T6mU9b4= +github.com/elastic/ecs v1.12.0 h1:u6WZ2AWtxv5vHvTQ4EuVZdWZ51mKHQ2UIltRePcta5U= github.com/elastic/ecs v1.12.0/go.mod h1:pgiLbQsijLOJvFR8OTILLu0Ni/R/foUNg0L+T6mU9b4= -github.com/elastic/elastic-agent-client/v7 v7.0.0-20210727140539-f0905d9377f6/go.mod h1:uh/Gj9a0XEbYoM4NYz4LvaBVARz3QXLmlNjsrKY9fTc= github.com/elastic/elastic-agent-client/v7 v7.0.0-20220607160924-1a71765a8bbe h1:knHO5fYAT3+sLf64NxcOxdjGysPxsSMkQGB27vMS8TE= github.com/elastic/elastic-agent-client/v7 v7.0.0-20220607160924-1a71765a8bbe/go.mod h1:fkvyUfFwyAG5OnMF0h+FV9sC0Xn9YLITwQpSuwungQs= -github.com/elastic/fsevents v0.0.0-20181029231046-e1d381a4d270/go.mod h1:Msl1pdboCbArMF/nSCDUXgQuWTeoMmE/z8607X+k7ng= +github.com/elastic/go-concert v0.2.0 h1:GAQrhRVXprnNjtvTP9pWJ1d4ToEA4cU5ci7TwTa20xg= github.com/elastic/go-concert v0.2.0/go.mod h1:HWjpO3IAEJUxOeaJOWXWEp7imKd27foxz9V5vegC/38= -github.com/elastic/go-libaudit v0.4.0/go.mod h1:lNJ7gX+arohEQTwqinAc8xycVuFNqsaunba1mwcBdvE= -github.com/elastic/go-libaudit/v2 v2.2.0/go.mod h1:MM/l/4xV7ilcl+cIblL8Zn448J7RZaDwgNLE4gNKYPg= -github.com/elastic/go-licenser v0.2.1/go.mod h1:D8eNQk70FOCVBl3smCGQt/lv7meBeQno2eI1S5apiHQ= github.com/elastic/go-licenser v0.3.1/go.mod h1:D8eNQk70FOCVBl3smCGQt/lv7meBeQno2eI1S5apiHQ= github.com/elastic/go-licenser v0.4.1 h1:1xDURsc8pL5zYT9R29425J3vkHdt4RT5TNEMeRN48x4= github.com/elastic/go-licenser v0.4.1/go.mod h1:V56wHMpmdURfibNBggaSBfqgPxyT1Tldns1i87iTEvU= -github.com/elastic/go-lookslike v0.3.0/go.mod h1:AhH+rdJux5RlVjs+6ej4jkvYyoNRkj2crxmqeHlj3hA= github.com/elastic/go-lumber v0.1.0 h1:HUjpyg36v2HoKtXlEC53EJ3zDFiDRn65d7B8dBHNius= github.com/elastic/go-lumber v0.1.0/go.mod h1:8YvjMIRYypWuPvpxx7WoijBYdbB7XIh/9FqSYQZTtxQ= -github.com/elastic/go-perf v0.0.0-20191212140718-9c656876f595/go.mod h1:s09U1b4P1ZxnKx2OsqY7KlHdCesqZWIhyq0Gs/QC/Us= -github.com/elastic/go-plugins-helpers v0.0.0-20200207104224-bdf17607b79f/go.mod h1:OPGqFNdTS34kMReS5hPFtBhD9J8itmSDurs1ix2wx7c= -github.com/elastic/go-seccomp-bpf v1.1.0 h1:jUzzDc6LyCtdolZdvL/26dad6rZ9vsc7xZ2eadKECAU= -github.com/elastic/go-seccomp-bpf v1.1.0/go.mod h1:l+89Vy5BzjVcaX8USZRMOwmwwDScE+vxCFzzvQwN7T8= +github.com/elastic/go-seccomp-bpf v1.2.0 h1:K5fToUAMzm0pmdlYORmw0FP0DloRa1SfqRYkum647Yk= github.com/elastic/go-seccomp-bpf v1.2.0/go.mod h1:l+89Vy5BzjVcaX8USZRMOwmwwDScE+vxCFzzvQwN7T8= -github.com/elastic/go-structform v0.0.6 h1:wqeK4LwD2NNDOoRGTImE24S6pkCDVr8+oUSIkmChzLk= -github.com/elastic/go-structform v0.0.6/go.mod h1:QrMyP3oM9Sjk92EVGLgRaL2lKt0Qx7ZNDRWDxB6khVs= +github.com/elastic/go-structform v0.0.9 h1:HpcS7xljL4kSyUfDJ8cXTJC6rU5ChL1wYb6cx3HLD+o= github.com/elastic/go-structform v0.0.9/go.mod h1:CZWf9aIRYY5SuKSmOhtXScE5uQiLZNqAFnwKR4OrIM4= github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= -github.com/elastic/go-sysinfo v1.3.0 h1:eb2XFGTMlSwG/yyU9Y8jVAYLIzU2sFzWXwo2gmetyrE= -github.com/elastic/go-sysinfo v1.3.0/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= -github.com/elastic/go-sysinfo v1.7.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= github.com/elastic/go-sysinfo v1.8.1 h1:4Yhj+HdV6WjbCRgGdZpPJ8lZQlXZLKDAeIkmQ/VRvi4= github.com/elastic/go-sysinfo v1.8.1/go.mod h1:JfllUnzoQV/JRYymbH3dO1yggI3mV2oTKSXsDHM+uIM= github.com/elastic/go-txfile v0.0.7 h1:Yn28gclW7X0Qy09nSMSsx0uOAvAGMsp6XHydbiLVe2s= github.com/elastic/go-txfile v0.0.7/go.mod h1:H0nCoFae0a4ga57apgxFsgmRjevNCsEaT6g56JoeKAE= github.com/elastic/go-ucfg v0.7.0/go.mod h1:iaiY0NBIYeasNgycLyTvhJftQlQEUO2hpF+FX0JKxzo= -github.com/elastic/go-ucfg v0.8.3 h1:leywnFjzr2QneZZWhE6uWd+QN/UpP0sdJRHYyuFvkeo= -github.com/elastic/go-ucfg v0.8.3/go.mod h1:iaiY0NBIYeasNgycLyTvhJftQlQEUO2hpF+FX0JKxzo= github.com/elastic/go-ucfg v0.8.6 h1:stUeyh2goTgGX+/wb9gzKvTv0YB0231LTpKUgCKj4U0= github.com/elastic/go-ucfg v0.8.6/go.mod h1:4E8mPOLSUV9hQ7sgLEJ4bvt0KhMuDJa8joDT2QGAEKA= github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU= github.com/elastic/go-windows v1.0.1 h1:AlYZOldA+UJ0/2nBuqWdo90GFCgG9xuyw9SYzGUtJm0= github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss= -github.com/elastic/gosigar v0.10.5 h1:GzPQ+78RaAb4J63unidA/JavQRKrB6s8IOzN6Ib59jo= -github.com/elastic/gosigar v0.10.5/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= +github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/elastic/sarama v0.0.0-20191122160421-355d120d0970 h1:rSo6gsz4zOanqtJ5fmZYQJvEJnA5YsVOB25casIwqUw= -github.com/elastic/sarama v0.0.0-20191122160421-355d120d0970/go.mod h1:fGP8eQ6PugKEI0iUETYYtnP6d1pH/bdDMTel1X5ajsU= -github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= -github.com/emersion/go-sasl v0.0.0-20211008083017-0b9dcfb154ac/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= -github.com/emersion/go-smtp v0.13.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ= -github.com/emersion/go-smtp v0.15.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ= +github.com/elastic/sarama v1.19.1-0.20210823122811-11c3ef800752 h1:5/RUNg7rkIvayjPhAIoI3v8p45NfWcfWs5DZSElycis= +github.com/elastic/sarama v1.19.1-0.20210823122811-11c3ef800752/go.mod h1:mdtqvCSg8JOxk8PmpTNGyo6wzd4BMm4QXSfDnTXmgkE= +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/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/emicklei/proto v1.9.0 h1:l0QiNT6Qs7Yj0Mb4X6dnWBQer4ebei2BFcgQLbGqUDc= -github.com/emicklei/proto v1.9.0/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= github.com/emicklei/proto v1.9.2 h1:YX2MPuUfUi/h8v+yt4WD8cdj6bt9P3475d2zrL0iogM= github.com/emicklei/proto v1.9.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -496,128 +152,69 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/fatih/color v1.5.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/frankban/quicktest v1.4.1 h1:Wv2VwvNn73pAdFIVUQRXYDFp31lXKbqblIXo/Q5GPSg= -github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= -github.com/fsnotify/fsevents v0.1.1/go.mod h1:+d+hS27T6k5J8CRaPLKFgwKYcpS7GwW3Ule9+SC2ZRc= -github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= -github.com/gabriel-vasile/mimetype v1.1.2 h1:gaPnPcNor5aZSVCJVSGipcpbgMWiAAj9z182ocSGbHU= -github.com/gabriel-vasile/mimetype v1.1.2/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To= +github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/gabriel-vasile/mimetype v1.4.0 h1:Cn9dkdYsMIu56tGho+fqzh7XmvY2YyGU0FnbhiOsEro= github.com/gabriel-vasile/mimetype v1.4.0/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8= -github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= -github.com/garyburd/redigo v1.0.1-0.20160525165706-b8dc90050f24/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= -github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc= -github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= -github.com/getkin/kin-openapi v0.9.0 h1:/vaUQkiOR+vfFO3oilZentZTfAhz7OzXPhLdNas4q4w= -github.com/getkin/kin-openapi v0.9.0/go.mod h1:zZQMFkVgRHCdhgb6ihCTIo9dyDZFvX0k/xAKqw1FhPw= -github.com/getkin/kin-openapi v0.76.0 h1:j77zg3Ec+k+r+GA3d8hBoXpAc6KX9TbBPrwQGBIy2sY= -github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= -github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/getkin/kin-openapi v0.67.0 h1:FGVL6Rs2ZWx/RrWdoRfqw74mrkClHOg3rW6knMk7VqQ= +github.com/getkin/kin-openapi v0.67.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= 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-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -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-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/go-ole/go-ole v1.2.5-0.20190920104607-14974a1cf647 h1:whypLownH338a3Ork2w9t0KUKtVxbXYySuz7V1YGsJo= github.com/go-ole/go-ole v1.2.5-0.20190920104607-14974a1cf647/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= 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/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= 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/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= 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-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-sourcemap/sourcemap v2.1.2+incompatible h1:0b/xya7BKGhXuqFESKM4oIiRo9WOt2ebz7KxfreD6ug= github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-task/slim-sprig v2.20.0+incompatible/go.mod h1:N/mhXZITr/EQAOErEHciKvO1bFei2Lld2Ym6h96pdy0= -github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= -github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= -github.com/gocarina/gocsv v0.0.0-20170324095351-ffef3ffc77be/go.mod h1:/oj50ZdPq/cUjA02lMZhijk5kR31SEydKyqah1OgBuo= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.5/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godror/godror v0.10.4/go.mod h1:9MVLtu25FBJBMHkPs0m3Ngf/VmwGcLpM2HS8PlNGw9U= github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/flock v0.7.2-0.20190320160742-5135e617513b h1:3QNh5Xo2pmr2nZXENtnztfpjej8XY8EPmvYxF5SzY9M= github.com/gofrs/flock v0.7.2-0.20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= -github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -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 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= -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-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= -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 h1:5ZkaAPbicIKTF2I64qf5Fh8Aa83Q/dnOafMYV0OMwjA= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= 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= @@ -625,12 +222,8 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 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 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= 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= @@ -644,54 +237,38 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.8.3 h1:HR0kYDX2RJZvAup8CsiJwxB4dTCSC0AaUq6S4SiLwUc= github.com/gomodule/redigo v1.8.3/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= 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/flatbuffers v1.7.2-0.20170925184458-7a6b2bf521e9/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/flatbuffers v1.12.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= +github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= 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 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= -github.com/google/go-github/v29 v29.0.2/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E= -github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= -github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gopacket v1.1.18-0.20191009163724-0ad7f2610e34/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= -github.com/google/licenseclassifier v0.0.0-20200402202327-879cb1424de0/go.mod h1:qsqn2hxC+vURpyBRygGUuinTO42MFRLcsmQ/P8v94+M= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= 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= @@ -702,224 +279,99 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -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-0.20190416172445-c2e93f3ae59f/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.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/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= -github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= -github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= -github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.3.1-0.20190624222214-25d8b0b66985/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= -github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= +github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorhill/cronexpr v0.0.0-20161205141322-d520615e531a/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 h1:f0n1xnMSmBLzVfsMMvriDyA75NB/oBgILX2GcHXIQzY= github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= -github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= -github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I= -github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= -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.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/h2non/filetype v1.1.1 h1:xvOwnXKAckvtLWsN398qS9QhlxlnVXBjXBydK2/UFB4= github.com/h2non/filetype v1.1.1/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= -github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= -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/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -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/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.2-0.20190520140433-59383c442f7d/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/hcl v1.0.1-0.20180906183839-65a6292f0157 h1:uyodBE3xDz0ynKs1tLBU26wOQoEkAqqiY18DbZ+FZrA= -github.com/hashicorp/hcl v1.0.1-0.20180906183839-65a6292f0157/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/nomad/api v0.0.0-20200303134319-e31695b5bbe6/go.mod h1:WKCL+tLVhN1D+APwH3JiTRZoxcdwRk86bWu1LVCUPaE= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/haya14busa/go-actions-toolkit v0.0.0-20200105081403-ca0307860f01/go.mod h1:1DWDZmeYf0LX30zscWb7K9rUMeirNeBMd5Dum+seUhc= -github.com/haya14busa/go-checkstyle v0.0.0-20170303121022-5e9d09f51fa1/go.mod h1:RsN5RGgVYeXpcXNtWyztD5VIe7VNSEqpJvF2iEH7QvI= -github.com/haya14busa/secretbox v0.0.0-20180525171038-07c7ecf409f5/go.mod h1:FGO/dXIFZnan7KvvUSFk1hYMnoVNzB6NTMPrmke8SSI= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= -github.com/imdario/mergo v0.3.9/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/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/insomniacslk/dhcp v0.0.0-20180716145214-633285ba52b2/go.mod h1:CfMdguCK66I5DAUJgGKyNz8aB6vO5dZzkm9Xep6WGvw= -github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= -github.com/jarcoal/httpmock v1.0.4/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= github.com/jcchavezs/porto v0.1.0/go.mod h1:fESH0gzDHiutHRdX2hv27ojnOVFco37hg1W6E9EZF4A= github.com/jcchavezs/porto v0.4.0 h1:Zj7RligrxmDdKGo6fBO2xYAHxEgrVBfs1YAja20WbV4= github.com/jcchavezs/porto v0.4.0/go.mod h1:fESH0gzDHiutHRdX2hv27ojnOVFco37hg1W6E9EZF4A= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= -github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.2 h1:6ZIM6b/JJN0X8UM43ZOM6Z4SJzla+a/u7scXFJzodkA= github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= +github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -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/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= -github.com/josephspurrier/goversioninfo v0.0.0-20190209210621-63e6d1acd3dd/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE= -github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 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.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/justinas/nosurf v1.1.0/go.mod h1:ALpWdSbuNGy2lZWtyXdjkYv4edL23oSEgfBT1gPJ5BQ= -github.com/kardianos/service v1.2.1-0.20210728001519-a323c3813bc7/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM= -github.com/karrick/godirwalk v1.15.6/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= -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.8.2 h1:Bx0qjetmNjdFXASH02NSAREKpiaDwkO1DRZ3dV2KCcs= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -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/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s= -github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4= -github.com/kong/go-kong v0.15.0 h1:9Y+7iqh7/0z8/BppAaLEV7ueSSyqK6lJOHFvqJnSSqM= -github.com/kong/go-kong v0.15.0/go.mod h1:oF4kdI9l/a8ndDW2ayJA0yhDBpO8Qt2aLiJEv10hqnQ= github.com/kong/go-kong v0.46.0 h1:9I6nlX63WymU5Sg+d13iZDVwpW5vXh8/v0zarU27dzI= github.com/kong/go-kong v0.46.0/go.mod h1:41Sot1N/n8UHBp+gE/6nOw3vuzoHbhMSyU/zOS7VzPE= github.com/kong/semver/v4 v4.0.1 h1:DIcNR8W3gfx0KabFBADPalxxsp+q/5COwIFkkhrFQ2Y= github.com/kong/semver/v4 v4.0.1/go.mod h1:LImQ0oT15pJvSns/hs2laLca2zcYoHu5EsSNY0J6/QA= 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 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80= @@ -933,422 +385,127 @@ github.com/lestrrat-go/jwx v1.2.26/go.mod h1:MaiCdGbn3/cckbOFSCluJlJMmp9dmZm5hDu github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.1.2-0.20190507191818-2ff3cb3adc01/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/magefile/mage v1.9.0 h1:t3AU2wNwehMCW97vuqQLtw6puppWXHO+O2MHo5a50XE= github.com/magefile/mage v1.9.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= -github.com/magefile/mage v1.11.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magefile/mage v1.13.0 h1:XtLJl8bcCM7EFoO8FyH8XK3t7G5hQAeK+i4tq+veT9M= github.com/magefile/mage v1.13.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/markbates/pkger v0.17.0/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= -github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= -github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11/go.mod h1:Ah2dBMoxZEqk118as2T4u4fjfXarE0pPnMJaArZQZsI= -github.com/mattn/go-colorable v0.0.8/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-ieproxy v0.0.0-20191113090002-7c0f6868bffe/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= -github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-shellwords v1.0.7/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -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/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.25 h1:dFwPR6SfLtrSwgDcIq2bcU/gVutB4sNApq2HBdqcakg= github.com/miekg/dns v1.1.25/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.29 h1:xHBEhR+t5RzcFJjBLJlax2daXOrTYtr9z4WdKEfWFzg= -github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -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/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/gox v1.0.1/go.mod h1:ED6BioOGXMswlXa2zxfh/xdd5QhwYliBFn9V18Ap4z4= -github.com/mitchellh/hashstructure v0.0.0-20170116052023-ab25296c0f51/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= -github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9dGS02Q3Y= -github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= github.com/mitchellh/hashstructure v1.1.0 h1:P6P1hdjqAAknpY/M1CGipelZgp+4y9ja9kmUZPXP+H0= github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/6d8ulp4AwfLKrmA= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg= -github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -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/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -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/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 h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -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/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= -github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -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/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -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.5.0/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.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= -github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= -github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= -github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= -github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= -github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= -github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= -github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= -github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= -github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.2.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= -github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= -github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= -github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= -github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= -github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= -github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= -github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= -github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= -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-rc1.0.20190228220655-ac19fd6e7483 h1:eFd3FsB01m/zNg/yBMYdm/XqiqCztcN9SVRPtGtzDHo= -github.com/opencontainers/go-digest v1.0.0-rc1.0.20190228220655-ac19fd6e7483/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/image-spec v1.0.2-0.20190823105129-775207bd45b6 h1:yN8BPXVwMBAm3Cuvh1L5XE8XpvYRMdsVLd82ILprhUU= github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6/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/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= -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/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/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/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/osquery/osquery-go v0.0.0-20210622151333-99b4efa62ec5/go.mod h1:JKR5QhjsYdnIPY7hakgas5sxf8qlA/9wQnLqaMfWdcg= -github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= -github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= -github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= -github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= -github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2/go.mod h1:L3UMQOThbttwfYRNFOWLLVXMhk5Lkio4GGOtw5UrxS0= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= -github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw= -github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= -github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw= github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/pierrec/lz4 v2.2.6+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= -github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.6.0+incompatible h1:Ix9yFKn1nSPBLFl/yZknTp8TU5G4Ps0JDmguYK6iH1A= github.com/pierrec/lz4 v2.6.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrre/gotestcover v0.0.0-20160113212533-7b94f124d338/go.mod h1:4xpMLz7RBWyB+ElzHu8Llua96TRCB3YwX+l5EP1wmHk= -github.com/pierrre/gotestcover v0.0.0-20160517101806-924dca7d15f0/go.mod h1:4xpMLz7RBWyB+ElzHu8Llua96TRCB3YwX+l5EP1wmHk= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1-0.20170505043639-c605e284fe17/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/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -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.1.1-0.20190913103102-20428fa0bffc/go.mod h1:ikMPikHu8SMvBGWoKulvvOOZN227amf2E9eMYqyAwAY= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -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.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -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-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -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.0.9-0.20191208103036-42f6e295b56f h1:i2BUTcG1g7lSgF/xVL4BJBAdrtNp4zL8woVTGHpEG4g= -github.com/prometheus/procfs v0.0.9-0.20191208103036-42f6e295b56f/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/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/prometheus v2.5.0+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rakyll/statik v0.1.6/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563 h1:dY6ETXrvDG7Sa4vE8ZQG4yqWg6UnOcbqTAahkV813vQ= -github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/reviewdog/errorformat v0.0.0-20200109134752-8983be9bc7dd/go.mod h1:giYAXnpegRDPsXUO7TRpDKXJo1lFGYxyWRfEt5iQ+OA= -github.com/reviewdog/reviewdog v0.9.17/go.mod h1:Y0yPFDTi9L5ohkoecJdgbvAhq+dUXp+zI7atqVibwKg= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= -github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8= -github.com/samuel/go-parser v0.0.0-20130731160455-ca8abbf65d0e/go.mod h1:Sb6li54lXV0yYEjI4wX8cucdQ9gqUJV3+Ngg3l9g30I= -github.com/samuel/go-thrift v0.0.0-20140522043831-2187045faa54/go.mod h1:Vrkh1pnjV9Bl8c3P9zH0/D4NlOHWP5d4/hF4YTULaec= -github.com/sanathkr/go-yaml v0.0.0-20170819195128-ed9d249f429b/go.mod h1:8458kAagoME2+LN5//WxE71ysZ3B7r22fdgb7qVmXSY= -github.com/sanathkr/yaml v0.0.0-20170819201035-0056894fa522/go.mod h1:tQTYKOQgxoH3v6dEmdHiz4JG+nbxWwM5fgPQUpSZqVQ= -github.com/sanathkr/yaml v1.0.1-0.20170819201035-0056894fa522/go.mod h1:tQTYKOQgxoH3v6dEmdHiz4JG+nbxWwM5fgPQUpSZqVQ= github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis= github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4= -github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shirou/gopsutil v2.19.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil v3.20.12+incompatible h1:6VEGkOXP/eP4o2Ilk8cSsX0PhOEfX6leqAnD+urrp9M= github.com/shirou/gopsutil v3.20.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -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 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= -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/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/snowzach/rotatefilehook v0.0.0-20180327172521-2f64f265f58c h1:iUEy7/LRto3JqR/GLXDTEFP+s+qIjWw4pM8yzMfXC9A= -github.com/snowzach/rotatefilehook v0.0.0-20180327172521-2f64f265f58c/go.mod h1:ZLVe3VfhAuMYLYWliGEydMBoRnfib8EFSqkBYu1ck9E= github.com/snowzach/rotatefilehook v0.0.0-20220211133110-53752135082d h1:4660u5vJtsyrn3QwJNfESwCws+TM1CMhRn123xjVyQ8= github.com/snowzach/rotatefilehook v0.0.0-20220211133110-53752135082d/go.mod h1:ZLVe3VfhAuMYLYWliGEydMBoRnfib8EFSqkBYu1ck9E= -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/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.3.0 h1:Ysnmjh1Di8EaWaBv40CYR4IdaIsBc5996Gh1oZzCBKk= -github.com/spf13/afero v1.3.0/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -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 v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= -github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= -github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= 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 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= -github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= -github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= -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.1.2-0.20180702103455-b8b73a35e983 h1:4s04gnPlcop3dmAHjOAHWa6gX7Dg7h0gh81gr3GwzIk= -github.com/stretchr/objx v0.1.2-0.20180702103455-b8b73a35e983/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/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.5.0/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 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/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs= github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= -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/tidwall/gjson v1.6.7 h1:Mb1M9HZCRWEcXQ8ieJo7auYyyiSux6w9XN3AdTpxJrE= -github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= -github.com/tidwall/gjson v1.6.8 h1:CTmXMClGYPAmln7652e69B7OLXfTi5ABcPPwjIWUv7w= -github.com/tidwall/gjson v1.6.8/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= -github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE= -github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU= -github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -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/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80/go.mod h1:iFyPdL66DjUD96XmzVL3ZntbzcflLnznH0fr99w5VqE= -github.com/tsg/go-daemon v0.0.0-20200207173439-e704b93fd89b/go.mod h1:jAqhj/JBVC1PwcLTWd6rjQyGyItxxrhpiBl8LSuAGmw= -github.com/tsg/gopacket v0.0.0-20190320122513-dd3d0e41124a h1:vVmCas8T0lbxAI1GuQO45L0o/OrWJSXtiK6vH27Qspg= -github.com/tsg/gopacket v0.0.0-20190320122513-dd3d0e41124a/go.mod h1:RIkfovP3Y7my19aXEjjbNd9E5TlHozzAyt7B8AaEcwg= -github.com/tsg/gopacket v0.0.0-20200626092518-2ab8e397a786/go.mod h1:RIkfovP3Y7my19aXEjjbNd9E5TlHozzAyt7B8AaEcwg= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.8/go.mod h1:0lNM99SwWUIRhCXnigEMClngXBk/EmpTXa7mgiewYWA= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.8/go.mod h1:X00B19HDtwvKbQY2DcYjvZxKQp8mzrJoQ6EgoIY/D2E= -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/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/tsg/gopacket v0.0.0-20200626092518-2ab8e397a786 h1:B/IVHYiI0d04dudYw+CvCAGqSMq8d0yWy56eD6p85BQ= +github.com/urso/diag v0.0.0-20200210123136-21b3cc8eb797 h1:OHNw/6pXODJAB32NujjdQO/KIYQ3KAbHQfCzH81XdCs= github.com/urso/diag v0.0.0-20200210123136-21b3cc8eb797/go.mod h1:pNWFTeQ+V1OYT/TzWpnWb6eQBdoXpdx+H+lrH97/Oyo= github.com/urso/go-bin v0.0.0-20180220135811-781c575c9f0e h1:NiofbjIUI5gR+ybDsGSVH1fWyjSeDYiYVJHT1+kcsak= github.com/urso/go-bin v0.0.0-20180220135811-781c575c9f0e/go.mod h1:6GfHrdWBQYjFRIznu7XuQH4lYB2w8nO4bnImVKkzPOM= @@ -1357,127 +514,66 @@ github.com/urso/magetools v0.0.0-20200106130147-61080ed7b22b h1:eRYRTx+2CteM4P2U github.com/urso/magetools v0.0.0-20200106130147-61080ed7b22b/go.mod h1:DFxTNgS/ExCGmmjVjSOgS2WjtfjKXgCyDzAFgbtovSA= github.com/urso/qcgen v0.0.0-20180131103024-0b059e7db4f4 h1:hhA8EBThzz9PztawVTycKvfETVuBqxAQ5keFlAVtbAw= github.com/urso/qcgen v0.0.0-20180131103024-0b059e7db4f4/go.mod h1:RspW+E2Yb7Fs7HclB2tiDaiu6Rp41BiIG4Wo1YaoXGc= +github.com/urso/sderr v0.0.0-20210525210834-52b04e8f5c71 h1:CehQeKbysHV8J2V7AD0w8NL2x1h04kmmo/Ft5su4lU0= github.com/urso/sderr v0.0.0-20210525210834-52b04e8f5c71/go.mod h1:Wp40HwmjM59FkDIVFfcCb9LzBbnc0XAMp8++hJuWvSU= -github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g= -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/vmware/govmomi v0.0.0-20170802214208-2cad15190b41/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= -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/xanzy/go-gitlab v0.22.3/go.mod h1:t4Bmvnxj7k37S4Y17lfLx+nLqkf/oQwT2HagfWKv5Og= -github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/scram v1.0.3 h1:nTadYh2Fs4BK2xdldEa2g5bbaZp0/+1nJMMPtPxS/to= github.com/xdg/scram v1.0.3/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= -github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xdg/stringprep v1.0.3 h1:cmL5Enob4W83ti/ZHuZLuKD/xqJfus4fVPwE+/BDm+4= github.com/xdg/stringprep v1.0.3/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/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/xeipuuv/gojsonschema v0.0.0-20181112162635-ac52e6811b56/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.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/gopher-lua v0.0.0-20170403160031-b402f3114ec7/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU= -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.elastic.co/apm v1.7.2/go.mod h1:tCw6CkOJgkWnzEthFN9HUP1uL3Gjc/Ur6m7gRPLaoH0= -go.elastic.co/apm v1.11.0/go.mod h1:qoOSi09pnzJDh5fKnfY7bPmQgl8yl2tULdOu03xhui0= go.elastic.co/apm v1.15.0 h1:uPk2g/whK7c7XiZyz/YCUnAUBNPiyNeE3ARX3G6Gx7Q= go.elastic.co/apm v1.15.0/go.mod h1:dylGv2HKR0tiCV+wliJz1KHtDyuD8SPe69oV7VyK6WY= +go.elastic.co/apm/module/apmelasticsearch v1.7.2 h1:5STGHLZLSeAzxordMc+dFVKiyVtMmxADOV+TgRaXXJg= go.elastic.co/apm/module/apmelasticsearch v1.7.2/go.mod h1:ZyNFuyWdt42GBZkz0SogoLzDBrBGj4orxpiUuxYeYq8= +go.elastic.co/apm/module/apmhttp v1.7.2 h1:2mRh7SwBuEVLmJlX+hsMdcSg9xaielCLElaPn/+i34w= go.elastic.co/apm/module/apmhttp v1.7.2/go.mod h1:sTFWiWejnhSdZv6+dMgxGec2Nxe/ZKfHfz/xtRM+cRY= -go.elastic.co/ecszap v0.3.0/go.mod h1:HTUi+QRmr3EuZMqxPX+5fyOdMNfUu5iPebgfhgsTJYQ= go.elastic.co/ecszap v1.0.1 h1:mBxqEJAEXBlpi5+scXdzL7LTFGogbuxipJC0KTZicyA= go.elastic.co/ecszap v1.0.1/go.mod h1:SVjazT+QgNeHSGOCUHvRgN+ZRj5FkB7IXQQsncdF57A= go.elastic.co/fastjson v1.0.0/go.mod h1:PmeUOMMtLHQr9ZS9J9owrAVg0FkaZDRZJEFTTGHtchs= go.elastic.co/fastjson v1.1.0 h1:3MrGBWWVIxe/xvsbpghtkFoPciPhOCmjsR/HfwEeQR4= go.elastic.co/fastjson v1.1.0/go.mod h1:boNGISWMjQsUPy/t6yqt2/1Wx4YNPSe+mZjlyw9vKKI= -go.elastic.co/go-licence-detector v0.4.0/go.mod h1:fSJQU8au4SAgDK+UQFbgUPsXKYNBDv4E/dwWevrMpXU= -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/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= -go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= -go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU= -go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= -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/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.uber.org/atomic v1.3.1/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.1.1-0.20170829224307-fb7d312c2c04 h1:8sYuFs2lovgFwQi15/wIkCkGX9sL8RouzbWUmBjTcXk= -go.uber.org/multierr v1.1.1-0.20170829224307-fb7d312c2c04/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.7.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -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-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/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-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= 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-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1517,43 +613,26 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181108082009-03003ca0c849/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-20181201002055-351d144fa1fc/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-20190213061140-3a22650c66bd/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-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/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-20191021144547-ec77196f6094/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191112182307-2180aed22343/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= @@ -1564,295 +643,162 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM= -golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-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-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= 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 h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/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-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190209173611-3b5209105503/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-20190222072716-a9d3bda3a223/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-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/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-20190529164535-6a60838ec259/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-20190813064441-fde4db37ae7a/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-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/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-20200102141924-c96a22e43c9c/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-20200116001909-b77594299b42/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 h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/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-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/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-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-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-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/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-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -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 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 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-20190907020128-2ca718005c18/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-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 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-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4 h1:Toz2IK7k8rbltAXwNAxKcn9OzqyNfMUhUNjz3sL0NMk= 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= @@ -1867,7 +813,6 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -1880,33 +825,20 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= -golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= 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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -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= @@ -1926,55 +858,27 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= -google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= -google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= -google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= -google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= -google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= -google.golang.org/api v0.81.0/go.mod h1:FA6Mb/bZxj706H2j+j2d6mHEEaHBmbbWnkfvmorOCko= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb h1:ADPHZzpzM4tk4V4S5cnCrr5SwzvlrPRmqqCuJDB8UTs= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -1994,75 +898,21 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211019152133-63b7e35f4404/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220426171045-31bebdecfb46/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220714211235-042d03aeabc9 h1:zfXhTgBfGlIh3jMXN06W8qbhFGsh6MJNJiYEuhTddOI= google.golang.org/genproto v0.0.0-20220714211235-042d03aeabc9/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= -google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= @@ -2074,23 +924,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= 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= @@ -2104,34 +939,19 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -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-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -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 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= 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/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= -gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= gopkg.in/hjson/hjson-go.v3 v3.0.1/go.mod h1:X6zrTSVeImfwfZLfgQdInl9mWjqPqgH90jom9nym/lw= -gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww= -gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw= @@ -2140,46 +960,27 @@ gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= gopkg.in/jcmturner/goidentity.v3 v3.0.0 h1:1duIyWiTaYvVx3YX2CYtpJbUFd7/UuPYCfgXtQ3VTbI= gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= -gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= gopkg.in/jcmturner/gokrb5.v7 v7.5.0 h1:a9tsXlIDD9SKxotJMK3niV7rPZAJeX2aD/0yg3qlIrg= gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU= gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= -gopkg.in/mgo.v2 v2.0.0-20160818020120-3f83fa500528/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= 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 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7/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 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c h1:grhR+C34yXImVGp7EzNk+DTIk+323eIUWOmEevy6bDo= -gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/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/gotestsum v0.6.0/go.mod h1:LEX+ioCVdeWhZc8GYfiBRag360eBhwixWJ62R9eDQtI= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -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= @@ -2187,66 +988,31 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh 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= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= -k8s.io/api v0.17.0 h1:H9d/lw+VkZKEVIUc8F3wgiQ+FUXTTr21M87jXLU7yqM= -k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI= -k8s.io/apimachinery v0.17.0 h1:xRBnuie9rXcPxUkDizUsGvPf1cnlZCFu210op7J7LJo= -k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= -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.17.0 h1:8QOGvUGdqDMFrm9sD6IUFl256BcffynGoe80sxgTEDg= -k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k= -k8s.io/code-generator v0.27.3/go.mod h1:DPung1sI5vBgn4AGKtlPRQAyagj/ir/4jI55ipZHVww= -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-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/api v0.21.1 h1:94bbZ5NTjdINJEdzOkpS4vdPhkb1VFpTYC9zh43f75c= +k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s= +k8s.io/apimachinery v0.21.1 h1:Q6XuHGlj2xc+hlMCvqyYfbv3H7SRGn2c8NycxJquDVs= +k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= +k8s.io/client-go v0.21.1 h1:bhblWYLZKUu+pm50plvQF8WpY6TXdRRtcS/K9WauOj4= +k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20220902162205-c0856e24416d/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.4-0.20190719014911-6a023d6d0e09/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= -k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= -k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= -k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= -k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= -k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= -k8s.io/utils v0.0.0-20190712204705-3dccf664f023/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo= -k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= +k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -kernel.org/pub/linux/libs/security/libcap/cap v1.2.57/go.mod h1:uI99C3r4SXvJeuqoEtx/eWt7UbmfqqZ80H8q+9t/A7I= -kernel.org/pub/linux/libs/security/libcap/psx v1.2.57/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 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/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= 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/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.1.1-0.20190704183835-4cd0c284b15f h1:rBmJnclilUaQG3K5/iL9zD57jtKRimbK2bJQGqktcs8= -sigs.k8s.io/yaml v1.1.1-0.20190704183835-4cd0c284b15f/go.mod h1:JLeFbgenPHTQHNZeYbMLTT18IylpsFnR2+IHPl6wctA= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/pkg/common/common.go b/pkg/common/common.go new file mode 100644 index 0000000..bfe5a3c --- /dev/null +++ b/pkg/common/common.go @@ -0,0 +1,8 @@ +package common + +const ( + AttrServiceId = "serviceId" + AttrRouteId = "serviceId" + AttrChecksum = "checksum" + AttrAppID = "kongApplicationId" +) diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index ca7b35a..074daf6 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -19,7 +19,7 @@ import ( "github.com/Axway/agents-kong/pkg/subscription" klib "github.com/kong/go-kong/kong" - _ "github.com/Axway/agents-kong/pkg/subscription/apikey" // needed for apikey subscription initialization + _ "github.com/Axway/agents-kong/pkg/subscription/auth" // needed for apikey subscription initialization ) const kongHash = "kong-hash" diff --git a/pkg/subscription/apikey.go b/pkg/subscription/apikey.go deleted file mode 100644 index 986cfbf..0000000 --- a/pkg/subscription/apikey.go +++ /dev/null @@ -1,12 +0,0 @@ -package subscription - -import ( - "github.com/kong/go-kong/kong" -) - -type apiKey struct{} - -const name = "kong-apikey" - -func (*apiKey) AppliesTo(*kong.Route) { -} diff --git a/pkg/subscription/apikey/apikey.go b/pkg/subscription/apikey/apikey.go deleted file mode 100644 index f9e7e48..0000000 --- a/pkg/subscription/apikey/apikey.go +++ /dev/null @@ -1,206 +0,0 @@ -package apikey - -import ( - "context" - "fmt" - "strings" - - "github.com/Axway/agent-sdk/pkg/apic" - kutil "github.com/Axway/agents-kong/pkg/kong" - "github.com/Axway/agents-kong/pkg/subscription" - "github.com/kong/go-kong/kong" - "github.com/sirupsen/logrus" -) - -type apiKey struct { - kc *kong.Client -} - -const Name = "kong-apikey" - -const ( - keyPluginName = "key-auth" - propertyName = "api-key" -) - -func init() { - subscription.Register(func(kc *kong.Client) subscription.Handler { - return &apiKey{kc} - }) -} - -func (*apiKey) Name() string { - return Name -} - -func (*apiKey) APICPolicy() string { - return apic.Apikey -} - -// Schema returns the schema -func (*apiKey) Schema() apic.SubscriptionSchema { - schema := apic.NewSubscriptionSchema(Name) - - schema.AddProperty(propertyName, - "string", - "The api key. Leave empty for autogeneration", - "", - false, - nil) - - return schema -} - -// IsApplicable if this subscription method -// is applicable for a route with the given plugins. -func (*apiKey) IsApplicable(plugins map[string]*kong.Plugin) bool { - _, ok := plugins[keyPluginName] - return ok -} - -func (ak *apiKey) Subscribe(log logrus.FieldLogger, subs apic.Subscription) { - key, err := ak.doSubscribe(log, subs) - - if err != nil { - log.WithError(err).Error("Failed to subscribe") - subs.UpdateState(apic.SubscriptionFailedToSubscribe, err.Error()) - return - } - - subs.UpdateStateWithProperties(apic.SubscriptionActive, "", map[string]interface{}{propertyName: key}) -} - -func (ak *apiKey) doSubscribe(log logrus.FieldLogger, subs apic.Subscription) (string, error) { - key := subs.GetPropertyValue(propertyName) - - agentTag := "amplify-agent" - ctx := context.Background() - routeID := subs.GetRemoteAPIID() - subscriptionID := subs.GetID() - subscriptionName := subs.GetName() + "_" + subscriptionID - apicID := subs.GetApicID() - - route, err := ak.kc.Routes.Get(ctx, &routeID) - if err != nil { - return "", fmt.Errorf("failed to get route: %w", err) - } - consumerTags := []*string{&apicID, &agentTag} - - plugins := kutil.Plugins{PluginLister: ak.kc.Plugins} - ep, err := plugins.GetEffectivePlugins(*route.ID, *route.Service.ID) - if err != nil { - return "", fmt.Errorf("failed to list route plugins: %w", err) - } - - consumerRes, update, err := ak.createOrUpdateConsumer(subscriptionName, subscriptionID, consumerTags) - if err != nil { - return "", err - } - - if update { - ak.deleteAllKeys(*consumerRes.ID, subscriptionID) - } - - keyAuth := &kong.KeyAuth{ - Tags: consumerTags, - } - // generate key if not provided - if key != "" { - keyAuth.Key = &key - } - - keyAuthRes, err := ak.kc.KeyAuths.Create(ctx, consumerRes.ID, keyAuth) - if err != nil { - return "", fmt.Errorf("failed to create API Key: %w", err) - } - - acl, ok := ep["acl"] - if !ok { - log.Warn("ACL Plugin is not configured on route / service") - return "", nil - } - - // add group - if groups, ok := acl.Config["allow"].([]interface{}); ok { - group := findACLGroup(groups) - - if group == "" { - return "", fmt.Errorf("failed to find suitable acl group") - } - - _, err = ak.kc.ACLs.Create(ctx, consumerRes.ID, &kong.ACLGroup{Group: &group, Tags: consumerTags}) - if err != nil { - return "", fmt.Errorf("failed to add acl group on consumer: %w", err) - } - } else { - log.Warn("No restrictions on API anybody can call it") - } - - return *keyAuthRes.Key, nil -} - -func (ak *apiKey) createOrUpdateConsumer(name string, customID string, tags []*string) (*kong.Consumer, bool, error) { - ctx := context.TODO() - - consumerRes, err := ak.kc.Consumers.Get(ctx, &name) - if err == nil { - return consumerRes, false, nil - } - - consumerRes, err = ak.kc.Consumers.Create(ctx, &kong.Consumer{ - CustomID: &customID, - Username: &name, - Tags: tags, - }) - if err != nil { - return nil, false, fmt.Errorf("failed to create consumer: %w", err) - } - - return consumerRes, true, nil -} - -func (ak *apiKey) Unsubscribe(log logrus.FieldLogger, subs apic.Subscription) { - log.Info("Delete apikey subscription") - subscriptionID := subs.GetID() - routeID := subs.GetRemoteAPIID() - subscriptionName := subs.GetName() + "_" + subscriptionID - ctx := context.Background() - - err := ak.kc.Consumers.Delete(ctx, &subscriptionName) - if err != nil { - log.WithError(err).Error("Failed to delete Consumer") - subs.UpdateState(apic.SubscriptionFailedToSubscribe, fmt.Sprintf("Failed to create API Key %s: %s", routeID, err)) - return - } - //subs.UpdateState(apic.SubscriptionUnsubscribed, "Toodles") - err = subs.UpdateState(apic.SubscriptionUnsubscribed, "Toodles") - if err != nil { - log.WithError(err).Error("failed to update subscription state") - } -} - -func findACLGroup(groups []interface{}) string { - for _, group := range groups { - if groupStr, ok := group.(string); ok && strings.HasPrefix(groupStr, "amplify.") { - return groupStr - } - } - return "" -} - -func (ak *apiKey) deleteAllKeys(consumerID, subscriptionID string) error { - ctx := context.Background() - keys, _, err := ak.kc.KeyAuths.ListForConsumer(ctx, &consumerID, &kong.ListOpt{Tags: []*string{&subscriptionID}}) - if err != nil { - return fmt.Errorf("failed to list all consumers: %w", err) - } - - for _, k := range keys { - err := ak.kc.KeyAuths.Delete(ctx, &consumerID, k.ID) - if err != nil { - return fmt.Errorf("failed to delete consumer key: ") - } - } - - return nil -} diff --git a/pkg/subscription/auth/apikey.go b/pkg/subscription/auth/apikey.go new file mode 100644 index 0000000..7376657 --- /dev/null +++ b/pkg/subscription/auth/apikey.go @@ -0,0 +1,137 @@ +package auth + +import ( + "context" + "errors" + "fmt" + "github.com/Axway/agent-sdk/pkg/apic" + "github.com/Axway/agent-sdk/pkg/apic/provisioning" + "github.com/Axway/agents-kong/pkg/common" + "github.com/Axway/agents-kong/pkg/subscription" + "github.com/kong/go-kong/kong" + "github.com/sirupsen/logrus" +) + +type apiKey struct { + kc *kong.Client +} + +const Name = "kong-apikey" + +const ( + propertyName = "api-key" +) + +func init() { + subscription.Register(func(kc *kong.Client) subscription.Handler { + return &apiKey{kc} + }) +} + +func (*apiKey) Name() string { + return Name +} + +func (*apiKey) APICPolicy() string { + return apic.Apikey +} + +// Schema returns the schema +func (*apiKey) Schema() apic.SubscriptionSchema { + schema := apic.NewSubscriptionSchema(Name) + + schema.AddProperty(propertyName, + "string", + "The api key. Leave empty for autogeneration", + "", + false, + nil) + + return schema +} + +func (ak *apiKey) deleteAllKeys(consumerID, subscriptionID string) error { + ctx := context.Background() + keys, _, err := ak.kc.KeyAuths.ListForConsumer(ctx, &consumerID, &kong.ListOpt{Tags: []*string{&subscriptionID}}) + if err != nil { + return fmt.Errorf("failed to list all consumers: %w", err) + } + + for _, k := range keys { + err := ak.kc.KeyAuths.Delete(ctx, &consumerID, k.ID) + if err != nil { + return fmt.Errorf("failed to delete consumer key: ") + } + } + + return nil +} + +func (ak *apiKey) UpdateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { + logrus.Info("provisioning credential update") + rs := provisioning.NewRequestStatusBuilder() + + ctx := context.Background() + agentTag := "amplify-agent" + consumerTags := []*string{&agentTag} + key := request.GetCredentialDetailsValue(propertyName) + consumerId := request.GetApplicationDetailsValue(common.AttrAppID) + + keyAuth := &kong.KeyAuth{ + Tags: consumerTags, + } + // generate key if not provided + if key != "" { + keyAuth.Key = &key + } + keyAuthRes, err := ak.kc.KeyAuths.Update(ctx, &consumerId, keyAuth) + if err != nil { + return subscription.Failed(rs, fmt.Errorf("failed to create API Key: %w", err)), nil + } + credential := provisioning.NewCredentialBuilder().SetAPIKey(*keyAuthRes.Key) + return rs.Success(), credential +} + +func (ak *apiKey) CreateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { + logrus.Info("provisioning credentials") + rs := provisioning.NewRequestStatusBuilder() + + ctx := context.Background() + agentTag := "amplify-agent" + consumerTags := []*string{&agentTag} + key := request.GetCredentialDetailsValue(propertyName) + consumerId := request.GetApplicationDetailsValue(common.AttrAppID) + + keyAuth := &kong.KeyAuth{ + Tags: consumerTags, + } + // generate key if not provided + if key != "" { + keyAuth.Key = &key + } + keyAuthRes, err := ak.kc.KeyAuths.Create(ctx, &consumerId, keyAuth) + if err != nil { + return subscription.Failed(rs, fmt.Errorf("failed to create API Key: %w", err)), nil + } + credential := provisioning.NewCredentialBuilder().SetAPIKey(*keyAuthRes.Key) + return rs.Success(), credential + +} + +func (ak *apiKey) DeleteCredential(request provisioning.CredentialRequest) provisioning.RequestStatus { + rs := provisioning.NewRequestStatusBuilder() + ctx := context.Background() + consumerId := request.GetCredentialDetailsValue(common.AttrAppID) + apiKeyId := request.GetCredentialDetailsValue(common.AttrAppID) + + logrus.Infof("consumerId : %s", consumerId) + if consumerId == "" { + return subscription.Failed(rs, errors.New("unable to delete Credential as consumerId is empty")) + } + err := ak.kc.KeyAuths.Delete(ctx, &consumerId, &apiKeyId) + if err != nil { + logrus.WithError(err).Error("Failed to delete Consumer") + return subscription.Failed(rs, errors.New(fmt.Sprintf("Failed to create API Key %s: %s", consumerId, err))) + } + return rs.Success() +} diff --git a/pkg/subscription/auth/basicauth.go b/pkg/subscription/auth/basicauth.go new file mode 100644 index 0000000..8832b06 --- /dev/null +++ b/pkg/subscription/auth/basicauth.go @@ -0,0 +1 @@ +package auth diff --git a/pkg/subscription/auth/jwt.go b/pkg/subscription/auth/jwt.go new file mode 100644 index 0000000..8832b06 --- /dev/null +++ b/pkg/subscription/auth/jwt.go @@ -0,0 +1 @@ +package auth diff --git a/pkg/subscription/auth/oauth2.go b/pkg/subscription/auth/oauth2.go new file mode 100644 index 0000000..8832b06 --- /dev/null +++ b/pkg/subscription/auth/oauth2.go @@ -0,0 +1 @@ +package auth diff --git a/pkg/subscription/package.go b/pkg/subscription/package.go deleted file mode 100644 index 5116318..0000000 --- a/pkg/subscription/package.go +++ /dev/null @@ -1,3 +0,0 @@ -package subscription - - diff --git a/pkg/subscription/provision.go b/pkg/subscription/provision.go new file mode 100644 index 0000000..00e0aae --- /dev/null +++ b/pkg/subscription/provision.go @@ -0,0 +1,264 @@ +package subscription + +import ( + "context" + "errors" + "fmt" + "github.com/Axway/agent-sdk/pkg/apic" + "github.com/Axway/agent-sdk/pkg/apic/provisioning" + "github.com/Axway/agent-sdk/pkg/util" + "github.com/Axway/agent-sdk/pkg/util/log" + "github.com/Axway/agents-kong/pkg/common" + kutil "github.com/Axway/agents-kong/pkg/kong" + "github.com/kong/go-kong/kong" + "github.com/sirupsen/logrus" +) + +const aclGroup = "amplify.group" + +type Info struct { + APICPolicyName string + SchemaName string +} + +var constructors []func(*kong.Client) Handler + +func Register(constructor func(*kong.Client) Handler) { + constructors = append(constructors, constructor) +} + +type Handler interface { + Schema() apic.SubscriptionSchema + Name() string + APICPolicy() string + CreateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) + DeleteCredential(request provisioning.CredentialRequest) provisioning.RequestStatus + UpdateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) +} + +type provisioner struct { + kc *kong.Client + log logrus.FieldLogger + handlers map[string]Handler +} + +func (p provisioner) CredentialUpdate(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { + p.log.Info("provisioning credentials update") + credentialType := request.GetCredentialType() + if h, ok := p.handlers[credentialType]; ok { + return h.UpdateCredential(request) + } + errorMsg := fmt.Sprintf("No known handler for type: %s", credentialType) + logrus.Info(errorMsg) + return Failed(provisioning.NewRequestStatusBuilder(), errors.New(errorMsg)), nil +} + +// NewProvisioner creates a type to implement the SDK Provisioning methods for handling subscriptions +func (p provisioner) NewProvisioner(kc *kong.Client, log logrus.FieldLogger) (provisioning.Provisioning, error) { + ctx := context.Background() + handlers := make(map[string]Handler, len(constructors)) + for _, c := range constructors { + h := c(kc) + handlers[h.Name()] = h + } + + plugins, err := kc.Plugins.ListAll(ctx) + if err != nil { + return nil, err + } + for _, plugin := range plugins { + if *plugin.Name == "acl" { + if groups, ok := plugin.Config["allow"].([]interface{}); ok { + allowedGroup := findACLGroup(groups) + logrus.Infof("Allowed ACL group %s", allowedGroup) + if allowedGroup == "" { + return nil, fmt.Errorf("failed to find acl with group value amplify.group") + } else { + return &provisioner{ + // set supported subscription handlers + kc: kc, + handlers: handlers, + log: log, + }, nil + } + + } + } + } + return nil, fmt.Errorf("failed to find acl with group value amplify.group") + +} + +func (p provisioner) ApplicationRequestProvision(request provisioning.ApplicationRequest) provisioning.RequestStatus { + p.log.Info("provisioning application") + ctx := context.Background() + rs := provisioning.NewRequestStatusBuilder() + appName := request.GetManagedApplicationName() + if appName == "" { + return Failed(rs, notFound("managed application name")) + } + + id := request.GetID() + consumer := kong.Consumer{ + CustomID: &id, + Username: &appName, + } + consumerResponse, err := p.kc.Consumers.Create(ctx, &consumer) + if err != nil { + return Failed(rs, errors.New("error creating consumer")) + } + // process application create + rs.AddProperty(common.AttrAppID, *consumerResponse.ID) + p.log. + WithField("appName", request.GetManagedApplicationName()). + Info("created application") + + return rs.Success() +} + +func (p provisioner) ApplicationRequestDeprovision(request provisioning.ApplicationRequest) provisioning.RequestStatus { + p.log.Info("de-provisioning application") + ctx := context.Background() + rs := provisioning.NewRequestStatusBuilder() + appID := request.GetApplicationDetailsValue(common.AttrAppID) + if appID == "" { + return Failed(rs, notFound(common.AttrAppID)) + } + consumerResponse, err := p.kc.Consumers.Get(ctx, &appID) + if err != nil { + return Failed(rs, errors.New("error getting consumer details")) + } + if consumerResponse == nil { + log.Warnf("Application with id %s is already deleted", appID) + return rs.Success() + } + err = p.kc.Consumers.Delete(ctx, &appID) + if err != nil { + return Failed(rs, errors.New("error deleting kong consumer")) + } + log.Infof("Application with Id %s deleted successfully on Kong", appID) + p.log. + WithField("appName", request.GetManagedApplicationName()). + WithField("appID", appID). + Info("removed application") + return rs.Success() +} +func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) (provisioning.RequestStatus, provisioning.AccessData) { + p.log.Info("provisioning access request") + agentTag := "amplify-agent" + ctx := context.Background() + rs := provisioning.NewRequestStatusBuilder() + instDetails := request.GetInstanceDetails() + serviceId := util.ToString(instDetails[common.AttrServiceId]) + routeId := util.ToString(instDetails[common.AttrRouteId]) + if serviceId == "" { + return Failed(rs, notFound(common.AttrServiceId)), nil + } + if routeId == "" { + return Failed(rs, notFound(common.AttrRouteId)), nil + } + kongApplicationId := request.GetApplicationDetailsValue(common.AttrAppID) + plugins := kutil.Plugins{PluginLister: p.kc.Plugins} + ep, err := plugins.GetEffectivePlugins(routeId, serviceId) + if err != nil { + return Failed(rs, fmt.Errorf("failed to list route plugins: %w", err)), nil + } + plugin, ok := ep["acl"] + if !ok { + log.Infof("ACL Plugin is not configured on route / service %s", serviceId) + _, err := p.kc.Plugins.CreateForService(ctx, &serviceId, plugin) + if err != nil { + return Failed(rs, fmt.Errorf("failed to add ACL pluing to service: %w", err)), nil + } + } + group := fmt.Sprintf("group=%s", aclGroup) + consumerTags := []*string{&agentTag} + + _, err = p.kc.ACLs.Create(ctx, &kongApplicationId, &kong.ACLGroup{Group: &group, Tags: consumerTags}) + if err != nil { + return Failed(rs, fmt.Errorf("failed to add acl group on consumer: %w", err)), nil + } + + // process access request create + rs.AddProperty(common.AttrAppID, kongApplicationId) + p.log. + WithField("api", serviceId). + WithField("app", request.GetApplicationName()). + Info("granted access") + return rs.Success(), nil +} +func (p provisioner) AccessRequestDeprovision(request provisioning.AccessRequest) provisioning.RequestStatus { + p.log.Info("deprovisioning access request") + rs := provisioning.NewRequestStatusBuilder() + instDetails := request.GetInstanceDetails() + + serviceId := util.ToString(instDetails[common.AttrServiceId]) + routeId := util.ToString(instDetails[common.AttrRouteId]) + + if serviceId == "" { + return Failed(rs, notFound(common.AttrServiceId)) + } + + if routeId == "" { + return Failed(rs, notFound(common.AttrRouteId)) + } + + // process access request delete + webmethodsApplicationId := request.GetAccessRequestDetailsValue(common.AttrAppID) + //GetApplicationDetailsValue(common.AttrAppID) + if webmethodsApplicationId == "" { + return Failed(rs, notFound(common.AttrAppID)) + } + //err := p.client.UnsubscribeApplication(webmethodsApplicationId, apiID) + //if err != nil { + // return Failed(rs, errors.New("Error removing API from Webmethods Application")) + //} + + p.log. + WithField("api", serviceId). + WithField("app", request.GetApplicationName()). + Info("removed access") + return rs.Success() +} +func (p provisioner) CredentialProvision(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { + + p.log.Info("provisioning credentials") + credentialType := request.GetCredentialType() + if h, ok := p.handlers[credentialType]; ok { + return h.CreateCredential(request) + } + errorMsg := fmt.Sprintf("No known handler for type: %s", credentialType) + logrus.Info(errorMsg) + return Failed(provisioning.NewRequestStatusBuilder(), errors.New(errorMsg)), nil +} +func (p provisioner) CredentialDeprovision(request provisioning.CredentialRequest) provisioning.RequestStatus { + p.log.Info("de_provisioning credentials") + + credentialType := request.GetCredentialType() + if h, ok := p.handlers[credentialType]; ok { + return h.DeleteCredential(request) + } + errorMsg := fmt.Sprintf("No known handler for type: %s", credentialType) + logrus.Info(errorMsg) + return Failed(provisioning.NewRequestStatusBuilder(), errors.New(errorMsg)) +} + +func Failed(rs provisioning.RequestStatusBuilder, err error) provisioning.RequestStatus { + logrus.Info("handle failed event") + rs.SetMessage(err.Error()) + logrus.Error(err) + return rs.Failed() +} + +func notFound(msg string) error { + return fmt.Errorf("%s not found", msg) +} + +func findACLGroup(groups []interface{}) string { + for _, group := range groups { + if groupStr, ok := group.(string); ok && groupStr == aclGroup { + return groupStr + } + } + return "" +} diff --git a/pkg/subscription/subscription_test.go b/pkg/subscription/subscription_test.go deleted file mode 100644 index 9cae2ab..0000000 --- a/pkg/subscription/subscription_test.go +++ /dev/null @@ -1,427 +0,0 @@ -package subscription_test - -import ( - "context" - "net/http" - "testing" - "time" - - "github.com/kong/go-kong/kong" - - "github.com/Axway/agent-sdk/pkg/agent" - "github.com/Axway/agent-sdk/pkg/apic" - "github.com/Axway/agent-sdk/pkg/config" - kutil "github.com/Axway/agents-kong/pkg/kong" - "github.com/Axway/agents-kong/pkg/subscription" - "github.com/sirupsen/logrus" - - _ "github.com/Axway/agents-kong/pkg/subscription/apikey" -) - -var swagger = ` -{ - "swagger": "2.0", - "info": { - "version": "1.0.0", - "title": "Swagger Petstore", - "description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification", - "termsOfService": "http://swagger.io/terms/", - "contact": { - "name": "Swagger API Team" - }, - "license": { - "name": "MIT" - } - }, - "host": "petstore.swagger.io", - "basePath": "/api", - "schemes": [ - "http" - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "paths": { - "/pets": { - "get": { - "description": "Returns all pets from the system that the user has access to", - "operationId": "findPets", - "produces": [ - "application/json", - "application/xml", - "text/xml", - "text/html" - ], - "parameters": [ - { - "name": "tags", - "in": "query", - "description": "tags to filter by", - "required": false, - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "csv" - }, - { - "name": "limit", - "in": "query", - "description": "maximum number of results to return", - "required": false, - "type": "integer", - "format": "int32" - } - ], - "responses": { - "200": { - "description": "pet response", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/Pet" - } - } - }, - "default": { - "description": "unexpected error", - "schema": { - "$ref": "#/definitions/ErrorModel" - } - } - } - }, - "post": { - "description": "Creates a new pet in the store. Duplicates are allowed", - "operationId": "addPet", - "produces": [ - "application/json" - ], - "parameters": [ - { - "name": "pet", - "in": "body", - "description": "Pet to add to the store", - "required": true, - "schema": { - "$ref": "#/definitions/NewPet" - } - } - ], - "responses": { - "200": { - "description": "pet response", - "schema": { - "$ref": "#/definitions/Pet" - } - }, - "default": { - "description": "unexpected error", - "schema": { - "$ref": "#/definitions/ErrorModel" - } - } - } - } - }, - "/pets/{id}": { - "get": { - "description": "Returns a user based on a single ID, if the user does not have access to the pet", - "operationId": "findPetById", - "produces": [ - "application/json", - "application/xml", - "text/xml", - "text/html" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "description": "ID of pet to fetch", - "required": true, - "type": "integer", - "format": "int64" - } - ], - "responses": { - "200": { - "description": "pet response", - "schema": { - "$ref": "#/definitions/Pet" - } - }, - "default": { - "description": "unexpected error", - "schema": { - "$ref": "#/definitions/ErrorModel" - } - } - } - }, - "delete": { - "description": "deletes a single pet based on the ID supplied", - "operationId": "deletePet", - "parameters": [ - { - "name": "id", - "in": "path", - "description": "ID of pet to delete", - "required": true, - "type": "integer", - "format": "int64" - } - ], - "responses": { - "204": { - "description": "pet deleted" - }, - "default": { - "description": "unexpected error", - "schema": { - "$ref": "#/definitions/ErrorModel" - } - } - } - } - } - }, - "definitions": { - "Pet": { - "type": "object", - "allOf": [ - { - "$ref": "#/definitions/NewPet" - }, - { - "required": [ - "id" - ], - "properties": { - "id": { - "type": "integer", - "format": "int64" - } - } - } - ] - }, - "NewPet": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string" - }, - "tag": { - "type": "string" - } - } - }, - "ErrorModel": { - "type": "object", - "required": [ - "code", - "message" - ], - "properties": { - "code": { - "type": "integer", - "format": "int32" - }, - "message": { - "type": "string" - } - } - } - } -} -` - -func stringP(in string) *string { - return &in -} - -func TestSubscription(t *testing.T) { - - // - // initialize central client - // set your client id, privateKey, publicKey below - // - err := agent.Initialize(&config.CentralConfiguration{ - AgentType: config.DiscoveryAgent, - Mode: config.PublishToEnvironmentAndCatalog, - TenantID: "251204211014979", - TeamName: "Default Team", - APICDeployment: "prod", - Environment: "vibu", - URL: "https://apicentral.axway.com", - PlatformURL: "https://platform.axway.com", - APIServerVersion: "v1alpha1", - TagsToPublish: "mytag", - AppendDataPlaneToTitle: true, - Auth: &config.AuthConfiguration{ - URL: "https://login.axway.com/auth", - Realm: "Broker", - ClientID: "DOSA_0acaa95063a64ff1ba4d76f2a35287b8", // change - PrivateKey: "/home/vibu/.xenutil/privateKey", // change - PublicKey: "/home/vibu/.xenutil/publicKey", // change - PrivateKeyData: "", - PublicKeyData: "", - KeyPwd: "", - Timeout: 0, - }, - PollInterval: 10, - ProxyURL: "", - SubscriptionConfiguration: config.NewSubscriptionConfig(), - }) - if err != nil { - t.Fatalf("Failed due: %s", err) - } - - // - // initialize kong client - // set your kong url below - // - - kURL := "http://localhost:8001" // change - - k, err := kong.NewClient(&kURL, &http.Client{}) - if err != nil { - t.Fatalf("Failed due: %s", err) - } - - // - // create test kong resources - // - name := stringP("petstore") - // create the route and service - svc, err := k.Services.Create(context.TODO(), &kong.Service{ - Name: name, - Host: stringP("petstore.swagger.io"), - Path: stringP("/v2"), - Protocol: stringP("http"), - }) - if err != nil { - if e, ok := err.(*kong.APIError); !ok || (ok && e.Code() != 409) { - t.Fatalf("Failed due: %s", err) - } - svc, err = k.Services.Get(context.TODO(), name) - if err != nil { - t.Fatalf("Failed due: %s", err) - } - } - route, err := k.Routes.CreateInService(context.TODO(), svc.ID, &kong.Route{ - Name: name, - Hosts: []*string{stringP("localhost")}, - Paths: []*string{stringP("/" + *name)}, - }) - if err != nil { - if e, ok := err.(*kong.APIError); !ok || (ok && e.Code() != 409) { - t.Fatalf("Failed due: %s", err) - } - route, err = k.Routes.Get(context.TODO(), name) - if err != nil { - t.Fatalf("Failed due: %s", err) - } - } - _, err = k.Plugins.Create(context.TODO(), &kong.Plugin{ - Name: stringP("key-auth"), - Route: route, - }) - if err != nil { - if e, ok := err.(*kong.APIError); !ok || (ok && e.Code() != 409) { - t.Fatalf("Failed due: %s", err) - } - } - _, err = k.Plugins.Create(context.TODO(), &kong.Plugin{ - Name: stringP("acl"), - Route: route, - Config: kong.Configuration{ - "allow": []interface{}{"amplify.testsvc"}, - }, - }) - if err != nil { - if e, ok := err.(*kong.APIError); !ok || (ok && e.Code() != 409) { - t.Fatalf("Failed due: %s", err) - } - } - - // - // this should happen as the agent is starting up - // - - sm := subscription.New(logrus.StandardLogger(), - agent.GetCentralClient(), - agent.GetCentralClient(), - k) - - // register schemas - for _, schema := range sm.Schemas() { - err := agent.GetCentralClient().RegisterSubscriptionSchema(schema) - if err != nil { - t.Fatalf("Failed due: %s", err) - } - } - - // register validator and handlers - agent.GetCentralClient().GetSubscriptionManager().RegisterValidator(sm.ValidateSubscription) - // register validator and handlers - agent.GetCentralClient().GetSubscriptionManager().RegisterProcessor(apic.SubscriptionApproved, sm.ProcessSubscribe) - agent.GetCentralClient().GetSubscriptionManager().RegisterProcessor(apic.SubscriptionUnsubscribeInitiated, sm.ProcessUnsubscribe) - - // start polling for subscriptions - agent.GetCentralClient().GetSubscriptionManager().Start() - - pl := kutil.Plugins{PluginLister: k.Plugins} - ep, err := pl.GetEffectivePlugins(*route.ID, *svc.ID) - if err != nil { - t.Fatalf("Failed due: %s", err) - } - - info := sm.GetSubscriptionInfo(ep) - // - // this should happen for each service - // - - sb := apic.ServiceBody{ - NameToPush: "vibu.testsvc", - APIName: "mytestapi", - RestAPIID: *route.ID, - URL: "https://myapi.com", - Version: "v1", - Swagger: []byte(swagger), - Tags: map[string]interface{}{"tag": nil}, - AgentMode: config.PublishToEnvironmentAndCatalog, - CreatedBy: "me", - Status: apic.PublishedStatus, - ServiceAttributes: map[string]string{"attr": "value"}, - AuthPolicy: info.APICPolicyName, - SubscriptionName: info.SchemaName, - } - - // - // Get the routeID and serviceID and pass them in here along with the ServiceBody - // If the routeID/serviceID have an key-auth plugin defined the right subscription - // will be defined - // - /* err = sm.PopulateSubscriptionParameters(*route.ID, *svc.ID, &sb) - if err != nil { - t.Fatalf("Failed due: %s", err) - } - */ - _, err = agent.GetCentralClient().PublishService(sb) - if err != nil { - t.Fatalf("Failed due: %s", err) - } - - // wait forever - for { - time.Sleep(time.Second) - } -} diff --git a/pkg/subscription/subscriptionmanager.go b/pkg/subscription/subscriptionmanager.go deleted file mode 100644 index 0f21c84..0000000 --- a/pkg/subscription/subscriptionmanager.go +++ /dev/null @@ -1,221 +0,0 @@ -package subscription - -import ( - "sync" - - "github.com/Axway/agent-sdk/pkg/apic" - "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" - "github.com/kong/go-kong/kong" - "github.com/sirupsen/logrus" -) - -var constructors = []func(*kong.Client) Handler{} - -func Register(constructor func(*kong.Client) Handler) { - constructors = append(constructors, constructor) -} - -// ConsumerInstanceGetter gets a consumer instance by id. -type ConsumerInstanceGetter interface { - GetConsumerInstanceByID(id string) (*management.ConsumerInstance, error) -} - -// SubscriptionGetter gets the all the subscription in any of the states for the catalog item with id -type SubscriptionGetter interface { - GetSubscriptionsForCatalogItem(states []string, id string) ([]apic.CentralSubscription, error) -} - -type Info struct { - APICPolicyName string - SchemaName string -} - -var defaultInfo = Info{apic.Passthrough, ""} - -type Handler interface { - Schema() apic.SubscriptionSchema - Name() string - APICPolicy() string - IsApplicable(map[string]*kong.Plugin) bool - Subscribe(log logrus.FieldLogger, subs apic.Subscription) - Unsubscribe(log logrus.FieldLogger, subs apic.Subscription) -} - -// Manager handles the subscription aspects -type Manager struct { - log logrus.FieldLogger - handlers map[string]Handler - cig ConsumerInstanceGetter - sg SubscriptionGetter - dg *duplicateGuard - // plugins *kutil.Plugins -} - -func New(log logrus.FieldLogger, - cig ConsumerInstanceGetter, - sg SubscriptionGetter, - kc *kong.Client) *Manager { - handlers := make(map[string]Handler, len(constructors)) - - for _, c := range constructors { - h := c(kc) - handlers[h.Name()] = h - } - - return &Manager{ - // set supported subscription handlers - handlers: handlers, - cig: cig, - log: log, - sg: sg, - dg: &duplicateGuard{ - cache: map[string]interface{}{}, - lock: &sync.Mutex{}, - }, - } -} - -func (sm *Manager) Schemas() []apic.SubscriptionSchema { - res := make([]apic.SubscriptionSchema, 0, len(sm.handlers)) - for _, h := range sm.handlers { - res = append(res, h.Schema()) - } - - return res -} - -// GetSubscriptionInfo returns the appropriate Info for the given set of plugins -func (sm *Manager) GetSubscriptionInfo(plugins map[string]*kong.Plugin) Info { - - for _, h := range sm.handlers { - if h.IsApplicable(plugins) { - return Info{APICPolicyName: h.APICPolicy(), SchemaName: h.Name()} - } - } - return defaultInfo -} - -func (sm *Manager) ValidateSubscription(subscription apic.Subscription) bool { - if sm.dg.markActive(subscription.GetID()) { - sm.log.Info("duplicate subscription event; already handling subscription") - return false - } - - return true -} - -type duplicateGuard struct { - cache map[string]interface{} - lock *sync.Mutex -} - -// markActive returns -func (dg *duplicateGuard) markActive(id string) bool { - dg.lock.Lock() - defer dg.lock.Unlock() - if _, ok := dg.cache[id]; ok { - return true - } - - dg.cache[id] = true - - return false -} - -// markActive returns -func (dg *duplicateGuard) markInactive(id string) bool { - dg.lock.Lock() - defer dg.lock.Unlock() - - delete(dg.cache, id) - return false -} - -func (sm *Manager) checkSubscriptionState(subscriptionID, catalogItemID, subscriptionState string) (bool, error) { - - subs, err := sm.sg.GetSubscriptionsForCatalogItem([]string{string(subscriptionState)}, catalogItemID) - if err != nil { - return false, err - } - - for _, sub := range subs { - if sub.GetID() == subscriptionID { - return true, nil - } - } - - return false, nil -} - -func (sm *Manager) ProcessSubscribe(subscription apic.Subscription) { - defer sm.dg.markInactive(subscription.GetID()) - log := sm.log. - WithField("subscriptionID", subscription.GetID()). - WithField("catalogItemID", subscription.GetCatalogItemID()). - WithField("remoteID", subscription.GetRemoteAPIID()). - WithField("consumerInstanceID", subscription.GetApicID()) - - isApproved, err := sm.checkSubscriptionState(subscription.GetID(), subscription.GetCatalogItemID(), string(apic.SubscriptionApproved)) - if err != nil { - log.WithError(err).Error("Failed to verify subscription state") - return - } - - if !isApproved { - log.Info("Subscription not in approved state. Nothing to do") - return - } - - log.Info("Processing subscription") - - ci, err := sm.cig.GetConsumerInstanceByID(subscription.GetApicID()) - if err != nil { - log.WithError(err).Error("Failed to fetch consumer instance") - return - } - - if h, ok := sm.handlers[ci.Spec.Subscription.SubscriptionDefinition]; ok { - h.Subscribe(log.WithField("handler", h.Name()), subscription) - } else { - log.Info("No known handler for type: ", ci.Spec.Subscription.SubscriptionDefinition) - } -} - -func (sm *Manager) ProcessUnsubscribe(subscription apic.Subscription) { - defer sm.dg.markInactive(subscription.GetID()) - - log := sm.log. - WithField("subscriptionID", subscription.GetID()). - WithField("catalogItemID", subscription.GetCatalogItemID()). - WithField("remoteID", subscription.GetRemoteAPIID()). - WithField("consumerInstanceID", subscription.GetApicID()) - - if sm.dg.markActive(subscription.GetID()) { - sm.log.Info("duplicate subscription event; already handling subscription") - } - isUnsubscribeInitiated, err := sm.checkSubscriptionState(subscription.GetID(), subscription.GetCatalogItemID(), string(apic.SubscriptionUnsubscribeInitiated)) - if err != nil { - log.WithError(err).Error("Failed to verify subscription state") - return - } - - if !isUnsubscribeInitiated { - log.Info("Subscription not in unsubscribe initiated state. Nothing to do") - return - } - - log.Info("Removing subscription") - - ci, err := sm.cig.GetConsumerInstanceByID(subscription.GetApicID()) - if err != nil { - log.WithError(err).Error("Failed to fetch consumer instance") - return - } - - if h, ok := sm.handlers[ci.Spec.Subscription.SubscriptionDefinition]; ok { - h.Unsubscribe(log.WithField("handler", h.Name()), subscription) - - } else { - log.Info("No known handler for type: ", ci.Spec.Subscription.SubscriptionDefinition) - } -} From 3828ff33a16298574015e52b97f122b70d693442 Mon Sep 17 00:00:00 2001 From: rathnapandi Date: Mon, 7 Aug 2023 16:28:42 -0700 Subject: [PATCH 37/76] - apikey & basic auth marketplace provisioning in progress --- pkg/common/common.go | 2 +- pkg/gateway/client.go | 275 +++++++++++-------- pkg/gateway/definitions.go | 49 ++-- pkg/subscription/auth/{ => apikey}/apikey.go | 37 +-- pkg/subscription/auth/basicauth.go | 1 - pkg/subscription/auth/basicauth/basicauth.go | 122 ++++++++ pkg/subscription/provision.go | 57 +--- 7 files changed, 349 insertions(+), 194 deletions(-) rename pkg/subscription/auth/{ => apikey}/apikey.go (84%) delete mode 100644 pkg/subscription/auth/basicauth.go create mode 100644 pkg/subscription/auth/basicauth/basicauth.go diff --git a/pkg/common/common.go b/pkg/common/common.go index bfe5a3c..9d1756a 100644 --- a/pkg/common/common.go +++ b/pkg/common/common.go @@ -2,7 +2,7 @@ package common const ( AttrServiceId = "serviceId" - AttrRouteId = "serviceId" + AttrRouteId = "routeId" AttrChecksum = "checksum" AttrAppID = "kongApplicationId" ) diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 074daf6..bf0207f 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -2,7 +2,13 @@ package gateway import ( "context" + "crypto/sha256" + "encoding/json" "fmt" + "github.com/Axway/agent-sdk/pkg/apic/provisioning" + "github.com/Axway/agents-kong/pkg/common" + "github.com/Axway/agents-kong/pkg/subscription" + "github.com/sirupsen/logrus" "net/http" "sync" @@ -12,18 +18,34 @@ import ( "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/apic" + "github.com/Axway/agent-sdk/pkg/cache" + "github.com/Axway/agent-sdk/pkg/util" "github.com/Axway/agent-sdk/pkg/util/log" config "github.com/Axway/agents-kong/pkg/config/discovery" kutil "github.com/Axway/agents-kong/pkg/kong" - "github.com/Axway/agents-kong/pkg/subscription" klib "github.com/kong/go-kong/kong" _ "github.com/Axway/agents-kong/pkg/subscription/auth" // needed for apikey subscription initialization ) -const kongHash = "kong-hash" -const kongServiceID = "kong-service-id" +const ( + AclGroup = "amplify.group" + marketplace = "marketplace" + // CorsField - + CorsField = "cors" + // RedirectURLsField - + RedirectURLsField = "redirectURLs" + OauthServerField = "oauthServer" + + OAuth2AuthType = "oauth2" + + ApplicationTypeField = "applicationType" + // ClientTypeField - + ClientTypeField = "clientType" + AudienceField = "audience" + OauthScopes = "oauthScopes" +) func NewClient(agentConfig config.AgentConfig) (*Client, error) { kongGatewayConfig := agentConfig.KongGatewayCfg @@ -32,30 +54,53 @@ func NewClient(agentConfig config.AgentConfig) (*Client, error) { if err != nil { return nil, err } - apicClient := NewCentralClient(agent.GetCentralClient(), agentConfig.CentralCfg) - if agentConfig.KongGatewayCfg.SpecDevPortalEnabled { specmanager.AddSource(devportal.NewSpecificationSource(kongClient)) } if len(agentConfig.KongGatewayCfg.SpecHomePath) > 0 { specmanager.AddSource(localdir.NewSpecificationSource(agentConfig.KongGatewayCfg.SpecHomePath)) } + daCache := cache.New() + logger := logrus.WithFields(logrus.Fields{ + "component": "agent", + }) - //sm, err := initSubscriptionManager(kongClient.Client) - //if err != nil { - // return nil, err - //} - + plugins, err := kongClient.Plugins.ListAll(context.Background()) + if err != nil { + return nil, err + } + for _, plugin := range plugins { + if *plugin.Name == "acl" { + if groups, ok := plugin.Config["allow"].([]interface{}); ok { + allowedGroup := findACLGroup(groups) + logrus.Infof("Allowed ACL group %s", allowedGroup) + if allowedGroup == "" { + return nil, fmt.Errorf("failed to find acl with group value amplify.group under allow") + } + } + } + } + subscription.NewProvisioner(kongClient.Client, logger) return &Client{ centralCfg: agentConfig.CentralCfg, kongGatewayCfg: kongGatewayConfig, kongClient: kongClient, apicClient: apicClient, - //subscriptionManager: sm, + cache: daCache, + mode: marketplace, }, nil } +func findACLGroup(groups []interface{}) string { + for _, group := range groups { + if groupStr, ok := group.(string); ok && groupStr == AclGroup { + return groupStr + } + } + return "" +} + func (gc *Client) DiscoverAPIs() error { plugins := kutil.Plugins{PluginLister: gc.kongClient.GetKongPlugins()} gc.plugins = plugins @@ -70,20 +115,16 @@ func (gc *Client) DiscoverAPIs() error { func (gc *Client) processKongServicesList(services []*klib.Service) { wg := new(sync.WaitGroup) - for _, service := range services { wg.Add(1) - go func(service *klib.Service, wg *sync.WaitGroup) { defer wg.Done() - err := gc.processSingleKongService(context.Background(), service) if err != nil { log.Error(err) } }(service, wg) } - wg.Wait() } @@ -103,13 +144,11 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se route := routes[0] - _, err = gc.plugins.GetEffectivePlugins(*route.ID, *service.ID) + apiPlugins, err := gc.plugins.GetEffectivePlugins(*route.ID, *service.ID) if err != nil { return fmt.Errorf("failed to get plugins for route %s: %w", *route.ID, err) } - // subscriptionInfo := gc.subscriptionManager.GetSubscriptionInfo(ep) - kongServiceSpec, err := specmanager.GetSpecification(ctx, service) if err != nil { return fmt.Errorf("failed to get spec for %s: %s", *service.Name, err) @@ -118,12 +157,8 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se oasSpec := Openapi{ spec: kongServiceSpec.Contents, } - endpoints := gc.processKongRoute(proxyEndpoint, oasSpec.BasePath(), route, httpPort, httpsPort) - subscriptionInfo := subscription.Info{} - - serviceBody, err := gc.processKongAPI(*route.ID, service, oasSpec, endpoints, subscriptionInfo) - //serviceBody, err := gc.processKongAPI(*route.ID, service, oasSpec, endpoints, subscriptionInfo) + serviceBody, err := gc.processKongAPI(*route.ID, service, oasSpec, endpoints, apiPlugins) if err != nil { return err @@ -132,34 +167,14 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se log.Debugf("not processing '%s' since no changes were detected", *service.Name) return nil } - err = agent.PublishAPI(*serviceBody) if err != nil { return fmt.Errorf("failed to publish api: %s", err) } - log.Infof("Published API '%s' to central", serviceBody.APIName) - return nil } -//func (gc *Client) deleteCentralService(serviceID string, serviceName string) { -// log.Debugf("kong service '%s' has no routes.", serviceName) -// item, _ := cache.GetCache().Get(serviceID) -// -// if svc, ok := item.(CachedService); ok { -// err := gc.apicClient.deleteCentralAPIService(svc) -// -// if err != nil { -// log.Errorf("failed to delete service '%' from central: %s", err) -// } else { -// log.Warnf("deleted Kong service '%s' from central", serviceName) -// } -// -// cache.GetCache().Delete(serviceID) -// } -//} - func (gc *Client) processKongRoute(defaultHost string, basePath string, route *klib.Route, httpPort, httpsPort int) []apic.EndpointDefinition { var endpoints []apic.EndpointDefinition if route == nil { @@ -200,26 +215,34 @@ func (gc *Client) processKongAPI( service *klib.Service, oasSpec Openapi, endpoints []apic.EndpointDefinition, - subscriptionInfo subscription.Info, + apiPlugins map[string]*klib.Plugin, ) (*apic.ServiceBody, error) { - name := *service.Name - kongAPI := newKongAPI(routeID, service, oasSpec, endpoints, name, subscriptionInfo) - + kongAPI := newKongAPI(routeID, service, oasSpec, endpoints) + isAlreadyPublished, checksum := isPublished(&kongAPI, gc.cache) + // If true, then the api is published and there were no changes detected + if isAlreadyPublished { + logrus.Debug("api is already published") + return nil, nil + } + err := gc.cache.Set(checksum, kongAPI) + if err != nil { + logrus.Errorf("failed to save api to cache: %s", err) + } + specType, _ := getSpecType(kongAPI.swaggerSpec) + logrus.Infof("Specification Type %s", specType) + ardName, crdName := getFirstAuthPluginArdAndCrd(apiPlugins) + kongAPI.accessRequestDefinition = ardName + kongAPI.CRDs = []string{crdName} + agentDetails := map[string]string{ + common.AttrServiceId: *service.ID, + common.AttrRouteId: routeID, + common.AttrChecksum: checksum, + } + kongAPI.agentDetails = agentDetails serviceBody, err := kongAPI.buildServiceBody() if err != nil { return nil, fmt.Errorf("failed to build service body: %v", serviceBody) } - - serviceBodyHash, _ := util.ComputeHash(serviceBody) - hash := fmt.Sprintf("%v", serviceBodyHash) - serviceBody.ServiceAttributes[kongHash] = hash - serviceBody.ServiceAttributes[kongServiceID] = *service.ID - - //isCached := setCachedService(*service.ID, *service.Name, hash, serviceBody.APIName) - //if isCached { - // return nil, nil - //} - return &serviceBody, nil } @@ -228,8 +251,6 @@ func newKongAPI( service *klib.Service, oasSpec Openapi, endpoints []apic.EndpointDefinition, - nameToPush string, - info subscription.Info, ) KongAPI { return KongAPI{ id: routeID, @@ -238,73 +259,109 @@ func newKongAPI( version: oasSpec.Version(), url: *service.Host, resourceType: oasSpec.ResourceType(), - documentation: []byte("\"Sample documentation for API discovery agent\""), + documentation: []byte(*service.Name), swaggerSpec: []byte(oasSpec.spec), endpoints: endpoints, - nameToPush: nameToPush, - //subscriptionInfo: info, } } func (ka *KongAPI) buildServiceBody() (apic.ServiceBody, error) { - serviceAttribute := make(map[string]string) - body := apic.NewServiceBodyBuilder(). + + tags := map[string]interface{}{} + if ka.tags != nil { + for _, tag := range ka.tags { + tags[tag] = true + } + } + + serviceAttributes := map[string]string{ + "GatewayType": "webMethods", + } + + return apic.NewServiceBodyBuilder(). SetAPIName(ka.name). SetAPISpec(ka.swaggerSpec). + SetAPIUpdateSeverity(ka.apiUpdateSeverity). + SetAuthPolicy(ka.subscriptionInfo.APICPolicyName). SetDescription(ka.description). SetDocumentation(ka.documentation). SetID(ka.id). + SetImage(ka.image). + SetImageContentType(ka.imageContentType). SetResourceType(ka.resourceType). - SetServiceAttribute(serviceAttribute). + SetServiceAgentDetails(util.MapStringStringToMapStringInterface(ka.agentDetails)). + SetServiceAttribute(serviceAttributes). + SetStage(ka.stage). + SetState(ka.state). + SetStatus(ka.status). + SetTags(tags). SetTitle(ka.name). SetURL(ka.url). SetVersion(ka.version). - SetAuthPolicy(ka.subscriptionInfo.APICPolicyName). - SetSubscriptionName(ka.subscriptionInfo.SchemaName).SetServiceEndpoints(ka.endpoints) + SetSubscriptionName(ka.subscriptionInfo.SchemaName).SetServiceEndpoints(ka.endpoints). + SetAccessRequestDefinitionName(ka.accessRequestDefinition, false). + SetCredentialRequestDefinitions(ka.CRDs).Build() +} + +func getSpecType(specContent []byte) (string, error) { + + if specContent != nil { + jsonMap := make(map[string]interface{}) + err := json.Unmarshal(specContent, &jsonMap) + if err != nil { + logrus.Info("Not an swagger or openapi spec") + return "", nil + } + if _, isSwagger := jsonMap["swagger"]; isSwagger { + return apic.Oas2, nil + } else if _, isOpenAPI := jsonMap["openapi"]; isOpenAPI { + return apic.Oas3, nil + } + } + return "", nil +} - sb, err := body.Build() +// makeChecksum generates a makeChecksum for the api for change detection +func makeChecksum(val interface{}) string { + sum := sha256.Sum256([]byte(fmt.Sprintf("%v", val))) + return fmt.Sprintf("%x", sum) +} - // TODO: add set method for NameToPush - if err == nil { - sb.NameToPush = ka.nameToPush +// isPublished checks if an api is published with the latest changes. Returns true if it is, and false if it is not. +func isPublished(api *KongAPI, c cache.Cache) (bool, string) { + // Change detection (asset + policies) + checksum := makeChecksum(api) + item, err := c.Get(checksum) + if err != nil || item == nil { + return false, checksum } + return true, checksum +} - return sb, err +func getFirstAuthPluginArdAndCrd(plugins map[string]*klib.Plugin) (string, string) { + for key := range plugins { + switch key { + case "key-auth": + return provisioning.APIKeyARD, provisioning.APIKeyCRD + case "jwt": + return "jwt", "jwt" + case "basic-auth": + return provisioning.BasicAuthARD, provisioning.BasicAuthCRD + case "oauth2": + return "oauth2", "oauth2" + } + + } + return "", "" } -//func doesServiceExists(serviceId string, services []*klib.Service) bool { -// for _, srv := range services { -// if serviceId == *srv.ID { -// return true -// } -// } -// log.Infof("Kong service '%s' no longer exists.", serviceId) -// -// return false -//} - -//func initSubscriptionManager(kc *klib.Client) (*subscription.Manager, error) { -// sm := subscription.New( -// logrus.StandardLogger(), -// agent.GetCentralClient(), -// agent.GetCentralClient(), -// kc) -// -// // register schemas -// for _, schema := range sm.Schemas() { -// if err := agent.GetCentralClient().RegisterSubscriptionSchema(schema); err != nil { -// return nil, fmt.Errorf("failed to register subscription schema %s: %w", schema.GetSubscriptionName(), err) -// } -// log.Infof("Schema registered: %s", schema.GetSubscriptionName()) -// } -// -// agent.GetCentralClient().GetSubscriptionManager().RegisterValidator(sm.ValidateSubscription) -// // register validator and handlers -// agent.GetCentralClient().GetSubscriptionManager().RegisterProcessor(apic.SubscriptionApproved, sm.ProcessSubscribe) -// agent.GetCentralClient().GetSubscriptionManager().RegisterProcessor(apic.SubscriptionUnsubscribeInitiated, sm.ProcessUnsubscribe) -// -// // start polling for subscriptions -// agent.GetCentralClient().GetSubscriptionManager().Start() -// -// return sm, nil -//} +func GetCorsSchemaPropertyBuilder() provisioning.PropertyBuilder { + return provisioning.NewSchemaPropertyBuilder(). + SetName(CorsField). + SetLabel("Javascript Origins"). + IsArray(). + AddItem( + provisioning.NewSchemaPropertyBuilder(). + SetName("Origins"). + IsString()) +} diff --git a/pkg/gateway/definitions.go b/pkg/gateway/definitions.go index 88e003f..b693139 100644 --- a/pkg/gateway/definitions.go +++ b/pkg/gateway/definitions.go @@ -5,32 +5,47 @@ import ( "github.com/Axway/agents-kong/pkg/kong" "github.com/Axway/agents-kong/pkg/subscription" + "github.com/Axway/agent-sdk/pkg/cache" corecfg "github.com/Axway/agent-sdk/pkg/config" + config "github.com/Axway/agents-kong/pkg/config/discovery" kutil "github.com/Axway/agents-kong/pkg/kong" ) type Client struct { - centralCfg corecfg.CentralConfig - kongGatewayCfg *config.KongGatewayConfig - kongClient kong.KongAPIClient - apicClient CentralClient - subscriptionManager *subscription.Manager - plugins kutil.Plugins + centralCfg corecfg.CentralConfig + kongGatewayCfg *config.KongGatewayConfig + kongClient kong.KongAPIClient + apicClient CentralClient + //subscriptionManager *subscription.Manager + plugins kutil.Plugins + cache cache.Cache + mode string } type KongAPI struct { - swaggerSpec []byte - id string - name string - description string - version string - url string - documentation []byte - resourceType string - endpoints []apic.EndpointDefinition - subscriptionInfo subscription.Info - nameToPush string + swaggerSpec []byte + id string + name string + description string + version string + url string + documentation []byte + resourceType string + endpoints []apic.EndpointDefinition + subscriptionInfo subscription.Info + image string + imageContentType string + CRDs []string + apiUpdateSeverity string + serviceAttributes map[string]string + agentDetails map[string]string + subscriptionName string + tags []string + stage string + state string + status string + accessRequestDefinition string } type CachedService struct { diff --git a/pkg/subscription/auth/apikey.go b/pkg/subscription/auth/apikey/apikey.go similarity index 84% rename from pkg/subscription/auth/apikey.go rename to pkg/subscription/auth/apikey/apikey.go index 7376657..fda1183 100644 --- a/pkg/subscription/auth/apikey.go +++ b/pkg/subscription/auth/apikey/apikey.go @@ -1,12 +1,13 @@ -package auth +package apikey import ( "context" "errors" "fmt" - "github.com/Axway/agent-sdk/pkg/apic" + "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/apic/provisioning" "github.com/Axway/agents-kong/pkg/common" + "github.com/Axway/agents-kong/pkg/gateway" "github.com/Axway/agents-kong/pkg/subscription" "github.com/kong/go-kong/kong" "github.com/sirupsen/logrus" @@ -23,7 +24,7 @@ const ( ) func init() { - subscription.Register(func(kc *kong.Client) subscription.Handler { + subscription.Add(func(kc *kong.Client) subscription.Handler { return &apiKey{kc} }) } @@ -32,22 +33,15 @@ func (*apiKey) Name() string { return Name } -func (*apiKey) APICPolicy() string { - return apic.Apikey -} - -// Schema returns the schema -func (*apiKey) Schema() apic.SubscriptionSchema { - schema := apic.NewSubscriptionSchema(Name) - - schema.AddProperty(propertyName, - "string", - "The api key. Leave empty for autogeneration", - "", - false, - nil) - - return schema +func (*apiKey) Register() { + //"The api key. Leave empty for autogeneration" + corsProp := gateway.GetCorsSchemaPropertyBuilder() + apiKeyProp := provisioning.NewSchemaPropertyBuilder(). + SetName(Name). + SetLabel(propertyName). + IsString() + agent.NewAPIKeyAccessRequestBuilder().Register() + agent.NewAPIKeyCredentialRequestBuilder(agent.WithCRDProvisionSchemaProperty(apiKeyProp), agent.WithCRDRequestSchemaProperty(corsProp)).IsRenewable().Register() } func (ak *apiKey) deleteAllKeys(consumerID, subscriptionID string) error { @@ -56,21 +50,18 @@ func (ak *apiKey) deleteAllKeys(consumerID, subscriptionID string) error { if err != nil { return fmt.Errorf("failed to list all consumers: %w", err) } - for _, k := range keys { err := ak.kc.KeyAuths.Delete(ctx, &consumerID, k.ID) if err != nil { return fmt.Errorf("failed to delete consumer key: ") } } - return nil } func (ak *apiKey) UpdateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { logrus.Info("provisioning credential update") rs := provisioning.NewRequestStatusBuilder() - ctx := context.Background() agentTag := "amplify-agent" consumerTags := []*string{&agentTag} @@ -95,7 +86,6 @@ func (ak *apiKey) UpdateCredential(request provisioning.CredentialRequest) (prov func (ak *apiKey) CreateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { logrus.Info("provisioning credentials") rs := provisioning.NewRequestStatusBuilder() - ctx := context.Background() agentTag := "amplify-agent" consumerTags := []*string{&agentTag} @@ -123,7 +113,6 @@ func (ak *apiKey) DeleteCredential(request provisioning.CredentialRequest) provi ctx := context.Background() consumerId := request.GetCredentialDetailsValue(common.AttrAppID) apiKeyId := request.GetCredentialDetailsValue(common.AttrAppID) - logrus.Infof("consumerId : %s", consumerId) if consumerId == "" { return subscription.Failed(rs, errors.New("unable to delete Credential as consumerId is empty")) diff --git a/pkg/subscription/auth/basicauth.go b/pkg/subscription/auth/basicauth.go deleted file mode 100644 index 8832b06..0000000 --- a/pkg/subscription/auth/basicauth.go +++ /dev/null @@ -1 +0,0 @@ -package auth diff --git a/pkg/subscription/auth/basicauth/basicauth.go b/pkg/subscription/auth/basicauth/basicauth.go new file mode 100644 index 0000000..c7b18a6 --- /dev/null +++ b/pkg/subscription/auth/basicauth/basicauth.go @@ -0,0 +1,122 @@ +package basicauth + +import ( + "context" + "errors" + "fmt" + "github.com/Axway/agent-sdk/pkg/agent" + "github.com/Axway/agent-sdk/pkg/apic/provisioning" + "github.com/Axway/agents-kong/pkg/common" + "github.com/Axway/agents-kong/pkg/gateway" + "github.com/Axway/agents-kong/pkg/subscription" + "github.com/kong/go-kong/kong" + "github.com/sirupsen/logrus" +) + +type basicAuth struct { + kc *kong.Client +} + +const Name = "kong-basic-auth" + +const ( + propertyName = "basic-auth" +) + +func init() { + subscription.Add(func(kc *kong.Client) subscription.Handler { + return &basicAuth{kc} + }) +} + +func (*basicAuth) Name() string { + return Name +} + +func (*basicAuth) Register() { + //"The api key. Leave empty for autogeneration" + corsProp := gateway.GetCorsSchemaPropertyBuilder() + agent.NewBasicAuthAccessRequestBuilder().Register() + agent.NewBasicAuthCredentialRequestBuilder(agent.WithCRDRequestSchemaProperty(corsProp)).IsRenewable().Register() +} + +func (auth *basicAuth) deleteAllKeys(consumerID, subscriptionID string) error { + ctx := context.Background() + keys, _, err := auth.kc.KeyAuths.ListForConsumer(ctx, &consumerID, &kong.ListOpt{Tags: []*string{&subscriptionID}}) + if err != nil { + return fmt.Errorf("failed to list all consumers: %w", err) + } + for _, k := range keys { + err := auth.kc.KeyAuths.Delete(ctx, &consumerID, k.ID) + if err != nil { + return fmt.Errorf("failed to delete consumer key: ") + } + } + return nil +} + +func (auth *basicAuth) UpdateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { + logrus.Info("provisioning credential update") + rs := provisioning.NewRequestStatusBuilder() + ctx := context.Background() + agentTag := "amplify-agent" + consumerTags := []*string{&agentTag} + username := request.GetCredentialDetailsValue(propertyName) + password := request.GetCredentialDetailsValue(propertyName) + consumerId := request.GetApplicationDetailsValue(common.AttrAppID) + + kongBasicAuth := kong.BasicAuth{ + Username: &username, + Password: &password, + Tags: consumerTags, + } + basicAuthResponse, err := auth.kc.BasicAuths.Create(ctx, &consumerId, &kongBasicAuth) + if err != nil { + return subscription.Failed(rs, fmt.Errorf("failed to create API Key: %w", err)), nil + } + credential := provisioning.NewCredentialBuilder().SetHTTPBasic(*basicAuthResponse.Username, *basicAuthResponse.Password) + return rs.Success(), credential + +} + +func (auth *basicAuth) CreateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { + logrus.Info("provisioning credentials") + rs := provisioning.NewRequestStatusBuilder() + ctx := context.Background() + agentTag := "amplify-agent" + consumerTags := []*string{&agentTag} + username := request.GetCredentialDetailsValue(propertyName) + password := request.GetCredentialDetailsValue(propertyName) + + consumerId := request.GetApplicationDetailsValue(common.AttrAppID) + + kongBasicAuth := kong.BasicAuth{ + Username: &username, + Password: &password, + Tags: consumerTags, + } + basicAuthResponse, err := auth.kc.BasicAuths.Create(ctx, &consumerId, &kongBasicAuth) + if err != nil { + return subscription.Failed(rs, fmt.Errorf("failed to create API Key: %w", err)), nil + } + credential := provisioning.NewCredentialBuilder().SetHTTPBasic(*basicAuthResponse.Username, *basicAuthResponse.Password) + return rs.Success(), credential + +} + +func (auth *basicAuth) DeleteCredential(request provisioning.CredentialRequest) provisioning.RequestStatus { + rs := provisioning.NewRequestStatusBuilder() + ctx := context.Background() + consumerId := request.GetCredentialDetailsValue(common.AttrAppID) + apiKeyId := request.GetCredentialDetailsValue(common.AttrAppID) + logrus.Infof("consumerId : %s", consumerId) + if consumerId == "" { + return subscription.Failed(rs, errors.New("unable to delete Credential as consumerId is empty")) + } + err := auth.kc.BasicAuths.Delete(ctx, &consumerId, &apiKeyId) + if err != nil { + logrus.WithError(err).Error("Failed to delete Consumer") + return subscription.Failed(rs, errors.New(fmt.Sprintf("Failed to create API Key %s: %s", consumerId, err))) + } + return rs.Success() +} diff --git a/pkg/subscription/provision.go b/pkg/subscription/provision.go index 00e0aae..3f86d92 100644 --- a/pkg/subscription/provision.go +++ b/pkg/subscription/provision.go @@ -4,18 +4,17 @@ import ( "context" "errors" "fmt" - "github.com/Axway/agent-sdk/pkg/apic" + "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/apic/provisioning" "github.com/Axway/agent-sdk/pkg/util" "github.com/Axway/agent-sdk/pkg/util/log" "github.com/Axway/agents-kong/pkg/common" + "github.com/Axway/agents-kong/pkg/gateway" kutil "github.com/Axway/agents-kong/pkg/kong" "github.com/kong/go-kong/kong" "github.com/sirupsen/logrus" ) -const aclGroup = "amplify.group" - type Info struct { APICPolicyName string SchemaName string @@ -23,14 +22,13 @@ type Info struct { var constructors []func(*kong.Client) Handler -func Register(constructor func(*kong.Client) Handler) { +func Add(constructor func(*kong.Client) Handler) { constructors = append(constructors, constructor) } type Handler interface { - Schema() apic.SubscriptionSchema + Register() Name() string - APICPolicy() string CreateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) DeleteCredential(request provisioning.CredentialRequest) provisioning.RequestStatus UpdateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) @@ -54,39 +52,23 @@ func (p provisioner) CredentialUpdate(request provisioning.CredentialRequest) (p } // NewProvisioner creates a type to implement the SDK Provisioning methods for handling subscriptions -func (p provisioner) NewProvisioner(kc *kong.Client, log logrus.FieldLogger) (provisioning.Provisioning, error) { - ctx := context.Background() +func NewProvisioner(kc *kong.Client, log logrus.FieldLogger) { handlers := make(map[string]Handler, len(constructors)) for _, c := range constructors { h := c(kc) + h.Register() handlers[h.Name()] = h } - - plugins, err := kc.Plugins.ListAll(ctx) - if err != nil { - return nil, err + provisioner := &provisioner{ + // set supported subscription handlers + kc: kc, + handlers: handlers, + log: log, } - for _, plugin := range plugins { - if *plugin.Name == "acl" { - if groups, ok := plugin.Config["allow"].([]interface{}); ok { - allowedGroup := findACLGroup(groups) - logrus.Infof("Allowed ACL group %s", allowedGroup) - if allowedGroup == "" { - return nil, fmt.Errorf("failed to find acl with group value amplify.group") - } else { - return &provisioner{ - // set supported subscription handlers - kc: kc, - handlers: handlers, - log: log, - }, nil - } - - } - } + agent.RegisterProvisioner(provisioner) + for _, handler := range handlers { + handler.Register() } - return nil, fmt.Errorf("failed to find acl with group value amplify.group") - } func (p provisioner) ApplicationRequestProvision(request provisioning.ApplicationRequest) provisioning.RequestStatus { @@ -171,7 +153,7 @@ func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) return Failed(rs, fmt.Errorf("failed to add ACL pluing to service: %w", err)), nil } } - group := fmt.Sprintf("group=%s", aclGroup) + group := fmt.Sprintf("group=%s", gateway.AclGroup) consumerTags := []*string{&agentTag} _, err = p.kc.ACLs.Create(ctx, &kongApplicationId, &kong.ACLGroup{Group: &group, Tags: consumerTags}) @@ -253,12 +235,3 @@ func Failed(rs provisioning.RequestStatusBuilder, err error) provisioning.Reques func notFound(msg string) error { return fmt.Errorf("%s not found", msg) } - -func findACLGroup(groups []interface{}) string { - for _, group := range groups { - if groupStr, ok := group.(string); ok && groupStr == aclGroup { - return groupStr - } - } - return "" -} From cd11a0dd887a38b67abd4d03d60020bcc8242670 Mon Sep 17 00:00:00 2001 From: rathnapandi Date: Tue, 8 Aug 2023 22:09:44 -0700 Subject: [PATCH 38/76] - validated access and credential request definition --- pkg/common/common.go | 16 ++++ pkg/gateway/client.go | 78 +++++++------------- pkg/kong/specmanager/localdir/localdir.go | 3 +- pkg/subscription/auth/apikey/apikey.go | 10 +-- pkg/subscription/auth/basicauth/basicauth.go | 7 +- pkg/subscription/provision.go | 60 +++++++++++---- 6 files changed, 96 insertions(+), 78 deletions(-) diff --git a/pkg/common/common.go b/pkg/common/common.go index 9d1756a..d5d37bd 100644 --- a/pkg/common/common.go +++ b/pkg/common/common.go @@ -5,4 +5,20 @@ const ( AttrRouteId = "routeId" AttrChecksum = "checksum" AttrAppID = "kongApplicationId" + + AclGroup = "amplify.group" + Marketplace = "marketplace" + // CorsField - + CorsField = "cors" + // RedirectURLsField - + RedirectURLsField = "redirectURLs" + OauthServerField = "oauthServer" + + OAuth2AuthType = "oauth2" + + ApplicationTypeField = "applicationType" + // ClientTypeField - + ClientTypeField = "clientType" + AudienceField = "audience" + OauthScopes = "oauthScopes" ) diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index bf0207f..e9600e8 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -3,7 +3,6 @@ package gateway import ( "context" "crypto/sha256" - "encoding/json" "fmt" "github.com/Axway/agent-sdk/pkg/apic/provisioning" "github.com/Axway/agents-kong/pkg/common" @@ -26,25 +25,8 @@ import ( kutil "github.com/Axway/agents-kong/pkg/kong" klib "github.com/kong/go-kong/kong" - _ "github.com/Axway/agents-kong/pkg/subscription/auth" // needed for apikey subscription initialization -) - -const ( - AclGroup = "amplify.group" - marketplace = "marketplace" - // CorsField - - CorsField = "cors" - // RedirectURLsField - - RedirectURLsField = "redirectURLs" - OauthServerField = "oauthServer" - - OAuth2AuthType = "oauth2" - - ApplicationTypeField = "applicationType" - // ClientTypeField - - ClientTypeField = "clientType" - AudienceField = "audience" - OauthScopes = "oauthScopes" + _ "github.com/Axway/agents-kong/pkg/subscription/auth/apikey" // needed for apikey subscription initialization + _ "github.com/Axway/agents-kong/pkg/subscription/auth/basicauth" // needed for basicAuth subscription initialization ) func NewClient(agentConfig config.AgentConfig) (*Client, error) { @@ -88,13 +70,14 @@ func NewClient(agentConfig config.AgentConfig) (*Client, error) { kongClient: kongClient, apicClient: apicClient, cache: daCache, - mode: marketplace, + mode: common.Marketplace, }, nil } func findACLGroup(groups []interface{}) string { for _, group := range groups { - if groupStr, ok := group.(string); ok && groupStr == AclGroup { + fmt.Println(group) + if groupStr, ok := group.(string); ok && groupStr == common.AclGroup { return groupStr } } @@ -228,8 +211,8 @@ func (gc *Client) processKongAPI( if err != nil { logrus.Errorf("failed to save api to cache: %s", err) } - specType, _ := getSpecType(kongAPI.swaggerSpec) - logrus.Infof("Specification Type %s", specType) + //specType, _ := getSpecType(kongAPI.swaggerSpec) + //logrus.Infof("Specification Type %s", specType) ardName, crdName := getFirstAuthPluginArdAndCrd(apiPlugins) kongAPI.accessRequestDefinition = ardName kongAPI.CRDs = []string{crdName} @@ -275,7 +258,7 @@ func (ka *KongAPI) buildServiceBody() (apic.ServiceBody, error) { } serviceAttributes := map[string]string{ - "GatewayType": "webMethods", + "GatewayType": "Kong API Gateway", } return apic.NewServiceBodyBuilder(). @@ -303,23 +286,23 @@ func (ka *KongAPI) buildServiceBody() (apic.ServiceBody, error) { SetCredentialRequestDefinitions(ka.CRDs).Build() } -func getSpecType(specContent []byte) (string, error) { - - if specContent != nil { - jsonMap := make(map[string]interface{}) - err := json.Unmarshal(specContent, &jsonMap) - if err != nil { - logrus.Info("Not an swagger or openapi spec") - return "", nil - } - if _, isSwagger := jsonMap["swagger"]; isSwagger { - return apic.Oas2, nil - } else if _, isOpenAPI := jsonMap["openapi"]; isOpenAPI { - return apic.Oas3, nil - } - } - return "", nil -} +//func getSpecType(specContent []byte) (string, error) { +// +// if specContent != nil { +// jsonMap := make(map[string]interface{}) +// err := json.Unmarshal(specContent, &jsonMap) +// if err != nil { +// logrus.Info("Not an swagger or openapi spec") +// return "", nil +// } +// if _, isSwagger := jsonMap["swagger"]; isSwagger { +// return apic.Oas2, nil +// } else if _, isOpenAPI := jsonMap["openapi"]; isOpenAPI { +// return apic.Oas3, nil +// } +// } +// return "", nil +//} // makeChecksum generates a makeChecksum for the api for change detection func makeChecksum(val interface{}) string { @@ -354,14 +337,3 @@ func getFirstAuthPluginArdAndCrd(plugins map[string]*klib.Plugin) (string, strin } return "", "" } - -func GetCorsSchemaPropertyBuilder() provisioning.PropertyBuilder { - return provisioning.NewSchemaPropertyBuilder(). - SetName(CorsField). - SetLabel("Javascript Origins"). - IsArray(). - AddItem( - provisioning.NewSchemaPropertyBuilder(). - SetName("Origins"). - IsString()) -} diff --git a/pkg/kong/specmanager/localdir/localdir.go b/pkg/kong/specmanager/localdir/localdir.go index d4a0a8e..0f620d7 100644 --- a/pkg/kong/specmanager/localdir/localdir.go +++ b/pkg/kong/specmanager/localdir/localdir.go @@ -3,7 +3,6 @@ package localdir import ( "context" "fmt" - "io/ioutil" "os" "path" "strings" @@ -56,7 +55,7 @@ func (sc sourceConfig) loadSpecFile(name string) (*specmanager.KongServiceSpec, return nil, nil } - data, err := ioutil.ReadFile(specFilePath) + data, err := os.ReadFile(specFilePath) if err != nil { return nil, fmt.Errorf("error on reading spec file %s: %s", specFilePath, err) } diff --git a/pkg/subscription/auth/apikey/apikey.go b/pkg/subscription/auth/apikey/apikey.go index fda1183..31cc621 100644 --- a/pkg/subscription/auth/apikey/apikey.go +++ b/pkg/subscription/auth/apikey/apikey.go @@ -7,7 +7,6 @@ import ( "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/apic/provisioning" "github.com/Axway/agents-kong/pkg/common" - "github.com/Axway/agents-kong/pkg/gateway" "github.com/Axway/agents-kong/pkg/subscription" "github.com/kong/go-kong/kong" "github.com/sirupsen/logrus" @@ -17,7 +16,7 @@ type apiKey struct { kc *kong.Client } -const Name = "kong-apikey" +const Name = provisioning.APIKeyARD const ( propertyName = "api-key" @@ -35,12 +34,13 @@ func (*apiKey) Name() string { func (*apiKey) Register() { //"The api key. Leave empty for autogeneration" - corsProp := gateway.GetCorsSchemaPropertyBuilder() + corsProp := subscription.GetCorsSchemaPropertyBuilder() apiKeyProp := provisioning.NewSchemaPropertyBuilder(). SetName(Name). SetLabel(propertyName). + SetDescription("The api key. Leave empty for auto generation"). IsString() - agent.NewAPIKeyAccessRequestBuilder().Register() + agent.NewAPIKeyAccessRequestBuilder().SetName(Name).Register() agent.NewAPIKeyCredentialRequestBuilder(agent.WithCRDProvisionSchemaProperty(apiKeyProp), agent.WithCRDRequestSchemaProperty(corsProp)).IsRenewable().Register() } @@ -91,7 +91,6 @@ func (ak *apiKey) CreateCredential(request provisioning.CredentialRequest) (prov consumerTags := []*string{&agentTag} key := request.GetCredentialDetailsValue(propertyName) consumerId := request.GetApplicationDetailsValue(common.AttrAppID) - keyAuth := &kong.KeyAuth{ Tags: consumerTags, } @@ -105,7 +104,6 @@ func (ak *apiKey) CreateCredential(request provisioning.CredentialRequest) (prov } credential := provisioning.NewCredentialBuilder().SetAPIKey(*keyAuthRes.Key) return rs.Success(), credential - } func (ak *apiKey) DeleteCredential(request provisioning.CredentialRequest) provisioning.RequestStatus { diff --git a/pkg/subscription/auth/basicauth/basicauth.go b/pkg/subscription/auth/basicauth/basicauth.go index c7b18a6..2bf9929 100644 --- a/pkg/subscription/auth/basicauth/basicauth.go +++ b/pkg/subscription/auth/basicauth/basicauth.go @@ -7,7 +7,6 @@ import ( "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/apic/provisioning" "github.com/Axway/agents-kong/pkg/common" - "github.com/Axway/agents-kong/pkg/gateway" "github.com/Axway/agents-kong/pkg/subscription" "github.com/kong/go-kong/kong" "github.com/sirupsen/logrus" @@ -17,7 +16,7 @@ type basicAuth struct { kc *kong.Client } -const Name = "kong-basic-auth" +const Name = provisioning.BasicAuthARD const ( propertyName = "basic-auth" @@ -35,8 +34,8 @@ func (*basicAuth) Name() string { func (*basicAuth) Register() { //"The api key. Leave empty for autogeneration" - corsProp := gateway.GetCorsSchemaPropertyBuilder() - agent.NewBasicAuthAccessRequestBuilder().Register() + corsProp := subscription.GetCorsSchemaPropertyBuilder() + agent.NewBasicAuthAccessRequestBuilder().SetName(Name).Register() agent.NewBasicAuthCredentialRequestBuilder(agent.WithCRDRequestSchemaProperty(corsProp)).IsRenewable().Register() } diff --git a/pkg/subscription/provision.go b/pkg/subscription/provision.go index 3f86d92..1e4710c 100644 --- a/pkg/subscription/provision.go +++ b/pkg/subscription/provision.go @@ -9,7 +9,6 @@ import ( "github.com/Axway/agent-sdk/pkg/util" "github.com/Axway/agent-sdk/pkg/util/log" "github.com/Axway/agents-kong/pkg/common" - "github.com/Axway/agents-kong/pkg/gateway" kutil "github.com/Axway/agents-kong/pkg/kong" "github.com/kong/go-kong/kong" "github.com/sirupsen/logrus" @@ -53,6 +52,8 @@ func (p provisioner) CredentialUpdate(request provisioning.CredentialRequest) (p // NewProvisioner creates a type to implement the SDK Provisioning methods for handling subscriptions func NewProvisioner(kc *kong.Client, log logrus.FieldLogger) { + logrus.Info("Registering provisioning callbacks") + logrus.Infof("Handlers : %d", len(constructors)) handlers := make(map[string]Handler, len(constructors)) for _, c := range constructors { h := c(kc) @@ -67,6 +68,7 @@ func NewProvisioner(kc *kong.Client, log logrus.FieldLogger) { } agent.RegisterProvisioner(provisioner) for _, handler := range handlers { + logrus.Infof("Registering authentication :%s", handler.Name()) handler.Register() } } @@ -79,13 +81,12 @@ func (p provisioner) ApplicationRequestProvision(request provisioning.Applicatio if appName == "" { return Failed(rs, notFound("managed application name")) } - id := request.GetID() consumer := kong.Consumer{ CustomID: &id, Username: &appName, } - consumerResponse, err := p.kc.Consumers.Create(ctx, &consumer) + consumerResponse, err := createConsumer(p.kc, consumer, ctx) if err != nil { return Failed(rs, errors.New("error creating consumer")) } @@ -140,6 +141,20 @@ func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) return Failed(rs, notFound(common.AttrRouteId)), nil } kongApplicationId := request.GetApplicationDetailsValue(common.AttrAppID) + if kongApplicationId == "" { + // Using the existing application + appName := request.GetApplicationName() + consumer := kong.Consumer{ + CustomID: &kongApplicationId, + Username: &appName, + } + var err error + consumerResponse, err := createConsumer(p.kc, consumer, ctx) + if err != nil { + return Failed(rs, errors.New("error creating kong consumer")), nil + } + kongApplicationId = *consumerResponse.ID + } plugins := kutil.Plugins{PluginLister: p.kc.Plugins} ep, err := plugins.GetEffectivePlugins(routeId, serviceId) if err != nil { @@ -153,14 +168,13 @@ func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) return Failed(rs, fmt.Errorf("failed to add ACL pluing to service: %w", err)), nil } } - group := fmt.Sprintf("group=%s", gateway.AclGroup) + group := fmt.Sprintf("group=%s", common.AclGroup) consumerTags := []*string{&agentTag} _, err = p.kc.ACLs.Create(ctx, &kongApplicationId, &kong.ACLGroup{Group: &group, Tags: consumerTags}) if err != nil { return Failed(rs, fmt.Errorf("failed to add acl group on consumer: %w", err)), nil } - // process access request create rs.AddProperty(common.AttrAppID, kongApplicationId) p.log. @@ -173,28 +187,20 @@ func (p provisioner) AccessRequestDeprovision(request provisioning.AccessRequest p.log.Info("deprovisioning access request") rs := provisioning.NewRequestStatusBuilder() instDetails := request.GetInstanceDetails() - serviceId := util.ToString(instDetails[common.AttrServiceId]) routeId := util.ToString(instDetails[common.AttrRouteId]) - if serviceId == "" { return Failed(rs, notFound(common.AttrServiceId)) } - if routeId == "" { return Failed(rs, notFound(common.AttrRouteId)) } - // process access request delete webmethodsApplicationId := request.GetAccessRequestDetailsValue(common.AttrAppID) //GetApplicationDetailsValue(common.AttrAppID) if webmethodsApplicationId == "" { return Failed(rs, notFound(common.AttrAppID)) } - //err := p.client.UnsubscribeApplication(webmethodsApplicationId, apiID) - //if err != nil { - // return Failed(rs, errors.New("Error removing API from Webmethods Application")) - //} p.log. WithField("api", serviceId). @@ -235,3 +241,31 @@ func Failed(rs provisioning.RequestStatusBuilder, err error) provisioning.Reques func notFound(msg string) error { return fmt.Errorf("%s not found", msg) } + +func createConsumer(kc *kong.Client, consumer kong.Consumer, ctx context.Context) (*kong.Consumer, error) { + consumerResponse, err := kc.Consumers.Get(ctx, consumer.CustomID) + if err != nil { + return nil, errors.New("error contacting Kong") + } + if consumerResponse == nil { + log.Infof("Creating new application with name %s", consumer.Username) + consumerResponse, err = kc.Consumers.Create(ctx, &consumer) + if err != nil { + return nil, errors.New("error creating consumer") + } + } else { + log.Infof("Using the existing consumer %s", consumer.Username) + } + return consumerResponse, nil +} + +func GetCorsSchemaPropertyBuilder() provisioning.PropertyBuilder { + return provisioning.NewSchemaPropertyBuilder(). + SetName(common.CorsField). + SetLabel("Javascript Origins"). + IsArray(). + AddItem( + provisioning.NewSchemaPropertyBuilder(). + SetName("Origins"). + IsString()) +} From b59efaf0e8addbf86d956f79a308f104879abc64 Mon Sep 17 00:00:00 2001 From: rathnapandi Date: Wed, 9 Aug 2023 14:45:06 -0700 Subject: [PATCH 39/76] - validated apikey subscription. --- pkg/gateway/client.go | 5 +++-- pkg/subscription/provision.go | 15 ++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index e9600e8..b674b3b 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -214,6 +214,7 @@ func (gc *Client) processKongAPI( //specType, _ := getSpecType(kongAPI.swaggerSpec) //logrus.Infof("Specification Type %s", specType) ardName, crdName := getFirstAuthPluginArdAndCrd(apiPlugins) + logrus.Infof("API %v Access Request Definition %s Credential Request Definition %s", kongAPI.name, ardName, crdName) kongAPI.accessRequestDefinition = ardName kongAPI.CRDs = []string{crdName} agentDetails := map[string]string{ @@ -275,8 +276,8 @@ func (ka *KongAPI) buildServiceBody() (apic.ServiceBody, error) { SetServiceAgentDetails(util.MapStringStringToMapStringInterface(ka.agentDetails)). SetServiceAttribute(serviceAttributes). SetStage(ka.stage). - SetState(ka.state). - SetStatus(ka.status). + SetState(apic.PublishedStatus). + SetStatus(apic.PublishedStatus). SetTags(tags). SetTitle(ka.name). SetURL(ka.url). diff --git a/pkg/subscription/provision.go b/pkg/subscription/provision.go index 1e4710c..ce72e07 100644 --- a/pkg/subscription/provision.go +++ b/pkg/subscription/provision.go @@ -88,7 +88,7 @@ func (p provisioner) ApplicationRequestProvision(request provisioning.Applicatio } consumerResponse, err := createConsumer(p.kc, consumer, ctx) if err != nil { - return Failed(rs, errors.New("error creating consumer")) + return Failed(rs, errors.New("error creating consumer "+err.Error())) } // process application create rs.AddProperty(common.AttrAppID, *consumerResponse.ID) @@ -168,9 +168,8 @@ func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) return Failed(rs, fmt.Errorf("failed to add ACL pluing to service: %w", err)), nil } } - group := fmt.Sprintf("group=%s", common.AclGroup) + group := common.AclGroup consumerTags := []*string{&agentTag} - _, err = p.kc.ACLs.Create(ctx, &kongApplicationId, &kong.ACLGroup{Group: &group, Tags: consumerTags}) if err != nil { return Failed(rs, fmt.Errorf("failed to add acl group on consumer: %w", err)), nil @@ -196,9 +195,9 @@ func (p provisioner) AccessRequestDeprovision(request provisioning.AccessRequest return Failed(rs, notFound(common.AttrRouteId)) } // process access request delete - webmethodsApplicationId := request.GetAccessRequestDetailsValue(common.AttrAppID) + kongConsumerId := request.GetAccessRequestDetailsValue(common.AttrAppID) //GetApplicationDetailsValue(common.AttrAppID) - if webmethodsApplicationId == "" { + if kongConsumerId == "" { return Failed(rs, notFound(common.AttrAppID)) } @@ -245,13 +244,11 @@ func notFound(msg string) error { func createConsumer(kc *kong.Client, consumer kong.Consumer, ctx context.Context) (*kong.Consumer, error) { consumerResponse, err := kc.Consumers.Get(ctx, consumer.CustomID) if err != nil { - return nil, errors.New("error contacting Kong") - } - if consumerResponse == nil { + log.Infof("Unable to find consumer application, Response from kong %s", err.Error()) log.Infof("Creating new application with name %s", consumer.Username) consumerResponse, err = kc.Consumers.Create(ctx, &consumer) if err != nil { - return nil, errors.New("error creating consumer") + return nil, err } } else { log.Infof("Using the existing consumer %s", consumer.Username) From 306626878b2682db4c5cbabd37ab74b59e0420a9 Mon Sep 17 00:00:00 2001 From: rathnapandi Date: Wed, 9 Aug 2023 16:30:37 -0700 Subject: [PATCH 40/76] - Support delete credential. --- pkg/common/common.go | 2 + pkg/gateway/client.go | 3 +- pkg/gateway/definitions.go | 5 +- pkg/subscription/auth/apikey/apikey.go | 16 ++- pkg/subscription/auth/basicauth/basicauth.go | 28 ++--- pkg/subscription/auth/jwt.go | 1 - pkg/subscription/auth/oauth2.go | 1 - pkg/subscription/auth/oauth2/oauth2.go | 122 +++++++++++++++++++ pkg/subscription/provision.go | 35 +++--- 9 files changed, 165 insertions(+), 48 deletions(-) delete mode 100644 pkg/subscription/auth/jwt.go delete mode 100644 pkg/subscription/auth/oauth2.go create mode 100644 pkg/subscription/auth/oauth2/oauth2.go diff --git a/pkg/common/common.go b/pkg/common/common.go index d5d37bd..8e3db10 100644 --- a/pkg/common/common.go +++ b/pkg/common/common.go @@ -6,6 +6,8 @@ const ( AttrChecksum = "checksum" AttrAppID = "kongApplicationId" + AttrCredentialID = "kongCredentialId" + AclGroup = "amplify.group" Marketplace = "marketplace" // CorsField - diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index b674b3b..d6659fc 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -266,7 +266,6 @@ func (ka *KongAPI) buildServiceBody() (apic.ServiceBody, error) { SetAPIName(ka.name). SetAPISpec(ka.swaggerSpec). SetAPIUpdateSeverity(ka.apiUpdateSeverity). - SetAuthPolicy(ka.subscriptionInfo.APICPolicyName). SetDescription(ka.description). SetDocumentation(ka.documentation). SetID(ka.id). @@ -282,7 +281,7 @@ func (ka *KongAPI) buildServiceBody() (apic.ServiceBody, error) { SetTitle(ka.name). SetURL(ka.url). SetVersion(ka.version). - SetSubscriptionName(ka.subscriptionInfo.SchemaName).SetServiceEndpoints(ka.endpoints). + SetServiceEndpoints(ka.endpoints). SetAccessRequestDefinitionName(ka.accessRequestDefinition, false). SetCredentialRequestDefinitions(ka.CRDs).Build() } diff --git a/pkg/gateway/definitions.go b/pkg/gateway/definitions.go index b693139..4434086 100644 --- a/pkg/gateway/definitions.go +++ b/pkg/gateway/definitions.go @@ -2,11 +2,9 @@ package gateway import ( "github.com/Axway/agent-sdk/pkg/apic" - "github.com/Axway/agents-kong/pkg/kong" - "github.com/Axway/agents-kong/pkg/subscription" - "github.com/Axway/agent-sdk/pkg/cache" corecfg "github.com/Axway/agent-sdk/pkg/config" + "github.com/Axway/agents-kong/pkg/kong" config "github.com/Axway/agents-kong/pkg/config/discovery" kutil "github.com/Axway/agents-kong/pkg/kong" @@ -33,7 +31,6 @@ type KongAPI struct { documentation []byte resourceType string endpoints []apic.EndpointDefinition - subscriptionInfo subscription.Info image string imageContentType string CRDs []string diff --git a/pkg/subscription/auth/apikey/apikey.go b/pkg/subscription/auth/apikey/apikey.go index 31cc621..a128c20 100644 --- a/pkg/subscription/auth/apikey/apikey.go +++ b/pkg/subscription/auth/apikey/apikey.go @@ -40,8 +40,14 @@ func (*apiKey) Register() { SetLabel(propertyName). SetDescription("The api key. Leave empty for auto generation"). IsString() - agent.NewAPIKeyAccessRequestBuilder().SetName(Name).Register() - agent.NewAPIKeyCredentialRequestBuilder(agent.WithCRDProvisionSchemaProperty(apiKeyProp), agent.WithCRDRequestSchemaProperty(corsProp)).IsRenewable().Register() + _, err := agent.NewAPIKeyAccessRequestBuilder().SetName(Name).Register() + if err != nil { + logrus.Error("Error registering API key Access Request") + } + _, err = agent.NewAPIKeyCredentialRequestBuilder(agent.WithCRDProvisionSchemaProperty(apiKeyProp), agent.WithCRDRequestSchemaProperty(corsProp)).IsRenewable().Register() + if err != nil { + logrus.Error("Error registering API Credential Access Request") + } } func (ak *apiKey) deleteAllKeys(consumerID, subscriptionID string) error { @@ -103,14 +109,18 @@ func (ak *apiKey) CreateCredential(request provisioning.CredentialRequest) (prov return subscription.Failed(rs, fmt.Errorf("failed to create API Key: %w", err)), nil } credential := provisioning.NewCredentialBuilder().SetAPIKey(*keyAuthRes.Key) + rs.AddProperty(common.AttrAppID, consumerId) + rs.AddProperty(common.AttrCredentialID, *keyAuthRes.ID) return rs.Success(), credential } func (ak *apiKey) DeleteCredential(request provisioning.CredentialRequest) provisioning.RequestStatus { + + logrus.Infof("%+v\n", request) rs := provisioning.NewRequestStatusBuilder() ctx := context.Background() consumerId := request.GetCredentialDetailsValue(common.AttrAppID) - apiKeyId := request.GetCredentialDetailsValue(common.AttrAppID) + apiKeyId := request.GetCredentialDetailsValue(common.AttrCredentialID) logrus.Infof("consumerId : %s", consumerId) if consumerId == "" { return subscription.Failed(rs, errors.New("unable to delete Credential as consumerId is empty")) diff --git a/pkg/subscription/auth/basicauth/basicauth.go b/pkg/subscription/auth/basicauth/basicauth.go index 2bf9929..e9374b3 100644 --- a/pkg/subscription/auth/basicauth/basicauth.go +++ b/pkg/subscription/auth/basicauth/basicauth.go @@ -35,23 +35,14 @@ func (*basicAuth) Name() string { func (*basicAuth) Register() { //"The api key. Leave empty for autogeneration" corsProp := subscription.GetCorsSchemaPropertyBuilder() - agent.NewBasicAuthAccessRequestBuilder().SetName(Name).Register() - agent.NewBasicAuthCredentialRequestBuilder(agent.WithCRDRequestSchemaProperty(corsProp)).IsRenewable().Register() -} - -func (auth *basicAuth) deleteAllKeys(consumerID, subscriptionID string) error { - ctx := context.Background() - keys, _, err := auth.kc.KeyAuths.ListForConsumer(ctx, &consumerID, &kong.ListOpt{Tags: []*string{&subscriptionID}}) + _, err := agent.NewBasicAuthAccessRequestBuilder().SetName(Name).Register() if err != nil { - return fmt.Errorf("failed to list all consumers: %w", err) + logrus.Error("Failed to register Basic Auth Access request") } - for _, k := range keys { - err := auth.kc.KeyAuths.Delete(ctx, &consumerID, k.ID) - if err != nil { - return fmt.Errorf("failed to delete consumer key: ") - } + _, err = agent.NewBasicAuthCredentialRequestBuilder(agent.WithCRDRequestSchemaProperty(corsProp)).IsRenewable().Register() + if err != nil { + logrus.Error("Failed to register Basic Auth Credential request") } - return nil } func (auth *basicAuth) UpdateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { @@ -86,9 +77,7 @@ func (auth *basicAuth) CreateCredential(request provisioning.CredentialRequest) consumerTags := []*string{&agentTag} username := request.GetCredentialDetailsValue(propertyName) password := request.GetCredentialDetailsValue(propertyName) - consumerId := request.GetApplicationDetailsValue(common.AttrAppID) - kongBasicAuth := kong.BasicAuth{ Username: &username, Password: &password, @@ -99,20 +88,21 @@ func (auth *basicAuth) CreateCredential(request provisioning.CredentialRequest) return subscription.Failed(rs, fmt.Errorf("failed to create API Key: %w", err)), nil } credential := provisioning.NewCredentialBuilder().SetHTTPBasic(*basicAuthResponse.Username, *basicAuthResponse.Password) + rs.AddProperty(common.AttrAppID, consumerId) + rs.AddProperty(common.AttrCredentialID, *basicAuthResponse.ID) return rs.Success(), credential - } func (auth *basicAuth) DeleteCredential(request provisioning.CredentialRequest) provisioning.RequestStatus { rs := provisioning.NewRequestStatusBuilder() ctx := context.Background() consumerId := request.GetCredentialDetailsValue(common.AttrAppID) - apiKeyId := request.GetCredentialDetailsValue(common.AttrAppID) + credId := request.GetCredentialDetailsValue(common.AttrCredentialID) logrus.Infof("consumerId : %s", consumerId) if consumerId == "" { return subscription.Failed(rs, errors.New("unable to delete Credential as consumerId is empty")) } - err := auth.kc.BasicAuths.Delete(ctx, &consumerId, &apiKeyId) + err := auth.kc.BasicAuths.Delete(ctx, &consumerId, &credId) if err != nil { logrus.WithError(err).Error("Failed to delete Consumer") return subscription.Failed(rs, errors.New(fmt.Sprintf("Failed to create API Key %s: %s", consumerId, err))) diff --git a/pkg/subscription/auth/jwt.go b/pkg/subscription/auth/jwt.go deleted file mode 100644 index 8832b06..0000000 --- a/pkg/subscription/auth/jwt.go +++ /dev/null @@ -1 +0,0 @@ -package auth diff --git a/pkg/subscription/auth/oauth2.go b/pkg/subscription/auth/oauth2.go deleted file mode 100644 index 8832b06..0000000 --- a/pkg/subscription/auth/oauth2.go +++ /dev/null @@ -1 +0,0 @@ -package auth diff --git a/pkg/subscription/auth/oauth2/oauth2.go b/pkg/subscription/auth/oauth2/oauth2.go new file mode 100644 index 0000000..3cfd38b --- /dev/null +++ b/pkg/subscription/auth/oauth2/oauth2.go @@ -0,0 +1,122 @@ +package oauth2 + +import ( + "context" + "errors" + "fmt" + "github.com/Axway/agent-sdk/pkg/agent" + "github.com/Axway/agent-sdk/pkg/apic/provisioning" + "github.com/Axway/agents-kong/pkg/common" + "github.com/Axway/agents-kong/pkg/subscription" + "github.com/kong/go-kong/kong" + "github.com/sirupsen/logrus" +) + +type oauth2 struct { + kc *kong.Client +} + +const Name = "oauth2" + +const ( + clientId = "client_id" + clientSecret = "client_secret" +) + +func init() { + subscription.Add(func(kc *kong.Client) subscription.Handler { + return &oauth2{kc} + }) +} + +func (*oauth2) Name() string { + return Name +} + +func (*oauth2) Register() { + corsProp := subscription.GetCorsSchemaPropertyBuilder() + //apiKeyProp := provisioning.NewSchemaPropertyBuilder(). + // SetName(Name). + // SetLabel(propertyName). + // SetDescription("The api key. Leave empty for auto generation"). + // IsString() + _, err := agent.NewAccessRequestBuilder().SetName(Name).Register() + if err != nil { + logrus.Errorf("Error registering Oauth2 Access Request %v", err) + } + _, err = agent.NewOAuthCredentialRequestBuilder(agent.WithCRDRequestSchemaProperty(corsProp)).SetName(Name).IsRenewable().Register() + if err != nil { + logrus.Errorf("Error registering Oauth2 credential Request %v", err) + + } +} + +func (ak *oauth2) UpdateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { + logrus.Info("provisioning credential update") + rs := provisioning.NewRequestStatusBuilder() + ctx := context.Background() + agentTag := "amplify-agent" + consumerTags := []*string{&agentTag} + clientId := request.GetCredentialDetailsValue(clientId) + clientSecret := request.GetCredentialDetailsValue(clientSecret) + + consumerId := request.GetApplicationDetailsValue(common.AttrAppID) + oauth2Credential := &kong.Oauth2Credential{ + Tags: consumerTags, + } + // generate key if not provided + if clientId != "" && clientSecret == "" { + oauth2Credential.ClientID = &clientId + oauth2Credential.ClientSecret = &clientSecret + } + oauth2Res, err := ak.kc.Oauth2Credentials.Create(ctx, &consumerId, oauth2Credential) + if err != nil { + return subscription.Failed(rs, fmt.Errorf("failed to create API Key: %w", err)), nil + } + credential := provisioning.NewCredentialBuilder().SetOAuthIDAndSecret(*oauth2Res.ClientID, *oauth2Res.ClientSecret) + return rs.Success(), credential + +} + +func (ak *oauth2) CreateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { + logrus.Info("provisioning credentials") + rs := provisioning.NewRequestStatusBuilder() + ctx := context.Background() + agentTag := "amplify-agent" + consumerTags := []*string{&agentTag} + clientId := request.GetCredentialDetailsValue(clientId) + clientSecret := request.GetCredentialDetailsValue(clientSecret) + + consumerId := request.GetApplicationDetailsValue(common.AttrAppID) + oauth2Credential := &kong.Oauth2Credential{ + Tags: consumerTags, + } + // generate key if not provided + if clientId != "" && clientSecret == "" { + oauth2Credential.ClientID = &clientId + oauth2Credential.ClientSecret = &clientSecret + } + oauth2Res, err := ak.kc.Oauth2Credentials.Create(ctx, &consumerId, oauth2Credential) + if err != nil { + return subscription.Failed(rs, fmt.Errorf("failed to create API Key: %w", err)), nil + } + credential := provisioning.NewCredentialBuilder().SetOAuthIDAndSecret(*oauth2Res.ClientID, *oauth2Res.ClientSecret) + return rs.Success(), credential +} + +func (ak *oauth2) DeleteCredential(request provisioning.CredentialRequest) provisioning.RequestStatus { + rs := provisioning.NewRequestStatusBuilder() + ctx := context.Background() + consumerId := request.GetCredentialDetailsValue(common.AttrAppID) + apiKeyId := request.GetCredentialDetailsValue(common.AttrAppID) + logrus.Infof("consumerId : %s", consumerId) + if consumerId == "" { + return subscription.Failed(rs, errors.New("unable to delete Credential as consumerId is empty")) + } + err := ak.kc.Oauth2Credentials.Delete(ctx, &consumerId, &apiKeyId) + if err != nil { + logrus.WithError(err).Error("Failed to delete Consumer") + return subscription.Failed(rs, errors.New(fmt.Sprintf("Failed to create API Key %s: %s", consumerId, err))) + } + return rs.Success() +} diff --git a/pkg/subscription/provision.go b/pkg/subscription/provision.go index ce72e07..8272939 100644 --- a/pkg/subscription/provision.go +++ b/pkg/subscription/provision.go @@ -14,11 +14,6 @@ import ( "github.com/sirupsen/logrus" ) -type Info struct { - APICPolicyName string - SchemaName string -} - var constructors []func(*kong.Client) Handler func Add(constructor func(*kong.Client) Handler) { @@ -39,17 +34,6 @@ type provisioner struct { handlers map[string]Handler } -func (p provisioner) CredentialUpdate(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { - p.log.Info("provisioning credentials update") - credentialType := request.GetCredentialType() - if h, ok := p.handlers[credentialType]; ok { - return h.UpdateCredential(request) - } - errorMsg := fmt.Sprintf("No known handler for type: %s", credentialType) - logrus.Info(errorMsg) - return Failed(provisioning.NewRequestStatusBuilder(), errors.New(errorMsg)), nil -} - // NewProvisioner creates a type to implement the SDK Provisioning methods for handling subscriptions func NewProvisioner(kc *kong.Client, log logrus.FieldLogger) { logrus.Info("Registering provisioning callbacks") @@ -73,6 +57,17 @@ func NewProvisioner(kc *kong.Client, log logrus.FieldLogger) { } } +func (p provisioner) CredentialUpdate(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { + p.log.Info("provisioning credentials update") + credentialType := request.GetCredentialType() + if h, ok := p.handlers[credentialType]; ok { + return h.UpdateCredential(request) + } + errorMsg := fmt.Sprintf("No known handler for type: %s", credentialType) + logrus.Info(errorMsg) + return Failed(provisioning.NewRequestStatusBuilder(), errors.New(errorMsg)), nil +} + func (p provisioner) ApplicationRequestProvision(request provisioning.ApplicationRequest) provisioning.RequestStatus { p.log.Info("provisioning application") ctx := context.Background() @@ -184,6 +179,7 @@ func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) } func (p provisioner) AccessRequestDeprovision(request provisioning.AccessRequest) provisioning.RequestStatus { p.log.Info("deprovisioning access request") + ctx := context.Background() rs := provisioning.NewRequestStatusBuilder() instDetails := request.GetInstanceDetails() serviceId := util.ToString(instDetails[common.AttrServiceId]) @@ -200,7 +196,11 @@ func (p provisioner) AccessRequestDeprovision(request provisioning.AccessRequest if kongConsumerId == "" { return Failed(rs, notFound(common.AttrAppID)) } - + group := common.AclGroup + err := p.kc.ACLs.Delete(ctx, &kongConsumerId, &group) + if err != nil { + return Failed(rs, fmt.Errorf("failed to remove acl group on consumer: %w", err)) + } p.log. WithField("api", serviceId). WithField("app", request.GetApplicationName()). @@ -220,7 +220,6 @@ func (p provisioner) CredentialProvision(request provisioning.CredentialRequest) } func (p provisioner) CredentialDeprovision(request provisioning.CredentialRequest) provisioning.RequestStatus { p.log.Info("de_provisioning credentials") - credentialType := request.GetCredentialType() if h, ok := p.handlers[credentialType]; ok { return h.DeleteCredential(request) From c2a606e53f1260645d0cb5e39fe39446d9bbb49d Mon Sep 17 00:00:00 2001 From: rathnapandi Date: Thu, 10 Aug 2023 16:42:34 -0700 Subject: [PATCH 41/76] - remove conflict in apikey attributes. - oauth2 support in progress --- pkg/gateway/client.go | 1 + pkg/subscription/auth/apikey/apikey.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index d6659fc..7802364 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -27,6 +27,7 @@ import ( _ "github.com/Axway/agents-kong/pkg/subscription/auth/apikey" // needed for apikey subscription initialization _ "github.com/Axway/agents-kong/pkg/subscription/auth/basicauth" // needed for basicAuth subscription initialization + _ "github.com/Axway/agents-kong/pkg/subscription/auth/oauth2" // needed for oauth2 subscription initialization ) func NewClient(agentConfig config.AgentConfig) (*Client, error) { diff --git a/pkg/subscription/auth/apikey/apikey.go b/pkg/subscription/auth/apikey/apikey.go index a128c20..8fe7ba3 100644 --- a/pkg/subscription/auth/apikey/apikey.go +++ b/pkg/subscription/auth/apikey/apikey.go @@ -19,7 +19,7 @@ type apiKey struct { const Name = provisioning.APIKeyARD const ( - propertyName = "api-key" + propertyName = "kong-api-key" ) func init() { From a57beb5575c64c01af14a5234641178c8e55e228 Mon Sep 17 00:00:00 2001 From: rathnapandi Date: Tue, 5 Sep 2023 19:44:58 -0700 Subject: [PATCH 42/76] - oauth2 support in progress - Quota support in progress. --- go.mod | 4 + pkg/common/common.go | 4 +- pkg/subscription/auth/oauth2/oauth2.go | 146 +++++++++++++++++++------ pkg/subscription/provision.go | 40 +++++++ 4 files changed, 160 insertions(+), 34 deletions(-) diff --git a/go.mod b/go.mod index 363e647..5e8629e 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,11 @@ module github.com/Axway/agents-kong go 1.18 +//replace ( +// github.com/Axway/agent-sdk => target latest + +replace github.com/Axway/agent-sdk => /Users/rnatarajan/GolandProjects/agent-sdk require ( github.com/Axway/agent-sdk v1.1.58 github.com/elastic/beats/v7 v7.17.5 diff --git a/pkg/common/common.go b/pkg/common/common.go index 8e3db10..0e0142e 100644 --- a/pkg/common/common.go +++ b/pkg/common/common.go @@ -11,7 +11,9 @@ const ( AclGroup = "amplify.group" Marketplace = "marketplace" // CorsField - - CorsField = "cors" + CorsField = "cors" + ProvisionKey = "provision_key" + // RedirectURLsField - RedirectURLsField = "redirectURLs" OauthServerField = "oauthServer" diff --git a/pkg/subscription/auth/oauth2/oauth2.go b/pkg/subscription/auth/oauth2/oauth2.go index 3cfd38b..d8b38c3 100644 --- a/pkg/subscription/auth/oauth2/oauth2.go +++ b/pkg/subscription/auth/oauth2/oauth2.go @@ -33,70 +33,107 @@ func (*oauth2) Name() string { return Name } -func (*oauth2) Register() { +// GetCredTypes - +func GetCredTypes() []string { + return []string{"confidential", "public"} +} + +func (a *oauth2) getAuthRedirectSchemaPropertyBuilder() provisioning.PropertyBuilder { + return provisioning.NewSchemaPropertyBuilder(). + SetName(common.RedirectURLsField). + SetLabel("Redirect URLs"). + IsArray(). + AddItem( + provisioning.NewSchemaPropertyBuilder(). + SetName("URL"). + IsString()) +} + +func (o *oauth2) Register() { + oAuthRedirects := o.getAuthRedirectSchemaPropertyBuilder() corsProp := subscription.GetCorsSchemaPropertyBuilder() - //apiKeyProp := provisioning.NewSchemaPropertyBuilder(). - // SetName(Name). - // SetLabel(propertyName). - // SetDescription("The api key. Leave empty for auto generation"). - // IsString() + provisionKey := subscription.GetProvisionKeyPropertyBuilder() + oAuthTypeProp := provisioning.NewSchemaPropertyBuilder(). + SetName(common.ApplicationTypeField). + SetRequired(). + SetLabel("Application Type"). + IsString(). + SetEnumValues(GetCredTypes()) + _, err := agent.NewAccessRequestBuilder().SetName(Name).Register() if err != nil { logrus.Errorf("Error registering Oauth2 Access Request %v", err) } - _, err = agent.NewOAuthCredentialRequestBuilder(agent.WithCRDRequestSchemaProperty(corsProp)).SetName(Name).IsRenewable().Register() + + _, err = agent.NewOAuthCredentialRequestBuilder( + agent.WithCRDOAuthSecret(), + agent.WithCRDRequestSchemaProperty(corsProp), + agent.WithCRDRequestSchemaProperty(oAuthTypeProp), + agent.WithCRDRequestSchemaProperty(oAuthRedirects), + agent.WithCRDIsRenewable(), + agent.WithCRDIsSuspendable(), + ).Register() + if err != nil { + logrus.Errorf("Error registering Oauth2 credential Request %v", err) + } + + _, err = agent.NewOAuthCredentialRequestBuilder(agent.WithCRDRequestSchemaProperty(corsProp), agent.WithCRDProvisionSchemaProperty(provisionKey)).SetName(Name).IsRenewable().Register() if err != nil { logrus.Errorf("Error registering Oauth2 credential Request %v", err) } } -func (ak *oauth2) UpdateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { +func (o *oauth2) UpdateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { logrus.Info("provisioning credential update") rs := provisioning.NewRequestStatusBuilder() ctx := context.Background() - agentTag := "amplify-agent" - consumerTags := []*string{&agentTag} - clientId := request.GetCredentialDetailsValue(clientId) - clientSecret := request.GetCredentialDetailsValue(clientSecret) - consumerId := request.GetApplicationDetailsValue(common.AttrAppID) - oauth2Credential := &kong.Oauth2Credential{ - Tags: consumerTags, - } - // generate key if not provided - if clientId != "" && clientSecret == "" { - oauth2Credential.ClientID = &clientId - oauth2Credential.ClientSecret = &clientSecret - } - oauth2Res, err := ak.kc.Oauth2Credentials.Create(ctx, &consumerId, oauth2Credential) + oauth2Credential := o.createOauthCredentialStruct(request) + oauth2Res, err := o.kc.Oauth2Credentials.Create(ctx, &consumerId, oauth2Credential) if err != nil { return subscription.Failed(rs, fmt.Errorf("failed to create API Key: %w", err)), nil } credential := provisioning.NewCredentialBuilder().SetOAuthIDAndSecret(*oauth2Res.ClientID, *oauth2Res.ClientSecret) return rs.Success(), credential - } -func (ak *oauth2) CreateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { - logrus.Info("provisioning credentials") - rs := provisioning.NewRequestStatusBuilder() - ctx := context.Background() +func (o *oauth2) createOauthCredentialStruct(request provisioning.CredentialRequest) *kong.Oauth2Credential { agentTag := "amplify-agent" consumerTags := []*string{&agentTag} clientId := request.GetCredentialDetailsValue(clientId) clientSecret := request.GetCredentialDetailsValue(clientSecret) + provData := o.getCredProvData(request.GetCredentialData()) - consumerId := request.GetApplicationDetailsValue(common.AttrAppID) oauth2Credential := &kong.Oauth2Credential{ Tags: consumerTags, } // generate key if not provided - if clientId != "" && clientSecret == "" { + if clientId != "" { oauth2Credential.ClientID = &clientId + } + + if clientSecret == "" { oauth2Credential.ClientSecret = &clientSecret } - oauth2Res, err := ak.kc.Oauth2Credentials.Create(ctx, &consumerId, oauth2Credential) + if len(provData.cors) > 0 { + var redirectUris []*string + for i := range provData.cors { + redirectUris = append(redirectUris, &provData.cors[i]) + } + oauth2Credential.RedirectURIs = redirectUris + } + oauth2Credential.ClientType = &provData.appType + return oauth2Credential +} + +func (o *oauth2) CreateCredential(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { + logrus.Info("provisioning credentials") + rs := provisioning.NewRequestStatusBuilder() + ctx := context.Background() + consumerId := request.GetApplicationDetailsValue(common.AttrAppID) + oauth2Credential := o.createOauthCredentialStruct(request) + oauth2Res, err := o.kc.Oauth2Credentials.Create(ctx, &consumerId, oauth2Credential) if err != nil { return subscription.Failed(rs, fmt.Errorf("failed to create API Key: %w", err)), nil } @@ -104,7 +141,7 @@ func (ak *oauth2) CreateCredential(request provisioning.CredentialRequest) (prov return rs.Success(), credential } -func (ak *oauth2) DeleteCredential(request provisioning.CredentialRequest) provisioning.RequestStatus { +func (o *oauth2) DeleteCredential(request provisioning.CredentialRequest) provisioning.RequestStatus { rs := provisioning.NewRequestStatusBuilder() ctx := context.Background() consumerId := request.GetCredentialDetailsValue(common.AttrAppID) @@ -113,10 +150,53 @@ func (ak *oauth2) DeleteCredential(request provisioning.CredentialRequest) provi if consumerId == "" { return subscription.Failed(rs, errors.New("unable to delete Credential as consumerId is empty")) } - err := ak.kc.Oauth2Credentials.Delete(ctx, &consumerId, &apiKeyId) + err := o.kc.Oauth2Credentials.Delete(ctx, &consumerId, &apiKeyId) if err != nil { - logrus.WithError(err).Error("Failed to delete Consumer") + logrus.WithError(err).Error("Failed to delete Oauth2 Credential") return subscription.Failed(rs, errors.New(fmt.Sprintf("Failed to create API Key %s: %s", consumerId, err))) } return rs.Success() } + +type credentialMetaData struct { + cors []string + redirectURLs []string + oauthServerName string + appType string + audience string +} + +func (o *oauth2) getCredProvData(credData map[string]interface{}) credentialMetaData { + // defaults + credMetaData := credentialMetaData{ + cors: []string{"*"}, + redirectURLs: []string{}, + appType: "Confidential", + audience: "", + } + + // get cors from credential request + if data, ok := credData[common.CorsField]; ok && data != nil { + credMetaData.cors = []string{} + for _, c := range data.([]interface{}) { + credMetaData.cors = append(credMetaData.cors, c.(string)) + } + } + // get redirectURLs + if data, ok := credData[common.RedirectURLsField]; ok && data != nil { + credMetaData.redirectURLs = []string{} + for _, u := range data.([]interface{}) { + credMetaData.redirectURLs = append(credMetaData.redirectURLs, u.(string)) + } + } + // Oauth Server field + if data, ok := credData[common.OauthServerField]; ok && data != nil { + credMetaData.oauthServerName = data.(string) + } + // credential type field + if data, ok := credData[common.ApplicationTypeField]; ok && data != nil { + credMetaData.appType = data.(string) + } + + return credMetaData +} diff --git a/pkg/subscription/provision.go b/pkg/subscription/provision.go index 8272939..b8a0be8 100644 --- a/pkg/subscription/provision.go +++ b/pkg/subscription/provision.go @@ -171,6 +171,24 @@ func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) } // process access request create rs.AddProperty(common.AttrAppID, kongApplicationId) + amplifyQuota := request.GetQuota() + if amplifyQuota != nil { + planName := amplifyQuota.GetPlanName() + planDesc := amplifyQuota.GetPlanName() + quotaLimit := int(amplifyQuota.GetLimit()) + p.log.Info(" Plan name :%s, Plan Description :%s Quota Limit: %s", planName, planDesc, quotaLimit) + config := kong.Configuration{ + "limit": []interface{}{quotaLimit}, + "policy": "local", + } + p.log.Info("%v", config) + //err := addRateLimit(p.kc, ctx, config, "") + //if err != nil { + // return nil, nil + //} + + //amplifyQuota.GetInterval(). + } p.log. WithField("api", serviceId). WithField("app", request.GetApplicationName()). @@ -265,3 +283,25 @@ func GetCorsSchemaPropertyBuilder() provisioning.PropertyBuilder { SetName("Origins"). IsString()) } + +func GetProvisionKeyPropertyBuilder() provisioning.PropertyBuilder { + return provisioning.NewSchemaPropertyBuilder(). + SetName(common.ProvisionKey). + SetLabel("Provision key"). + SetRequired(). + IsString() +} + +//func addRateLimit(kc *kong.Client, ctx context.Context, config map[string]interface{}, serviceId string) error { +// pluginName := "rate-limiting" +// rateLimitPlugin := kong.Plugin{ +// Name: &pluginName, +// Config: config, +// } +// kc.Do(ctx) +// //_, err := kc.Consumers.C(ctx, &serviceId, &rateLimitPlugin) +// if err != nil { +// return err +// } +// return nil +//} From 045fcc7406d29fac9e661990aa7b2c6eed648717 Mon Sep 17 00:00:00 2001 From: dgghinea-axway Date: Mon, 30 Oct 2023 17:24:02 +0200 Subject: [PATCH 43/76] validate ACL plugin --- pkg/cmd/discovery/discoveryCmd.go | 2 +- pkg/gateway/client.go | 31 +++++++++++++------------------ pkg/gateway/client_test.go | 19 +++++++++++++++++++ pkg/processor/eventmapper.go | 5 +++-- pkg/subscription/provision.go | 5 +++-- 5 files changed, 39 insertions(+), 23 deletions(-) create mode 100644 pkg/gateway/client_test.go diff --git a/pkg/cmd/discovery/discoveryCmd.go b/pkg/cmd/discovery/discoveryCmd.go index 5e97d66..8410aca 100644 --- a/pkg/cmd/discovery/discoveryCmd.go +++ b/pkg/cmd/discovery/discoveryCmd.go @@ -48,7 +48,7 @@ func run() error { for { err = gatewayClient.DiscoverAPIs() if err != nil { - log.Error("error in processing: %s", err) + log.Errorf("error in processing: %s", err) stopChan <- struct{}{} } log.Infof("next poll in %s", agentConfig.CentralCfg.GetPollInterval()) diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 7802364..40cc616 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -4,12 +4,13 @@ import ( "context" "crypto/sha256" "fmt" + "net/http" + "sync" + "github.com/Axway/agent-sdk/pkg/apic/provisioning" "github.com/Axway/agents-kong/pkg/common" "github.com/Axway/agents-kong/pkg/subscription" "github.com/sirupsen/logrus" - "net/http" - "sync" "github.com/Axway/agents-kong/pkg/kong/specmanager" "github.com/Axway/agents-kong/pkg/kong/specmanager/devportal" @@ -53,17 +54,11 @@ func NewClient(agentConfig config.AgentConfig) (*Client, error) { if err != nil { return nil, err } - for _, plugin := range plugins { - if *plugin.Name == "acl" { - if groups, ok := plugin.Config["allow"].([]interface{}); ok { - allowedGroup := findACLGroup(groups) - logrus.Infof("Allowed ACL group %s", allowedGroup) - if allowedGroup == "" { - return nil, fmt.Errorf("failed to find acl with group value amplify.group under allow") - } - } - } + + if err := hasACLEnabledInPlugins(plugins); err != nil { + return nil, err } + subscription.NewProvisioner(kongClient.Client, logger) return &Client{ centralCfg: agentConfig.CentralCfg, @@ -75,14 +70,14 @@ func NewClient(agentConfig config.AgentConfig) (*Client, error) { }, nil } -func findACLGroup(groups []interface{}) string { - for _, group := range groups { - fmt.Println(group) - if groupStr, ok := group.(string); ok && groupStr == common.AclGroup { - return groupStr +// Returns no error in case an ACL plugin which is enabled is found +func hasACLEnabledInPlugins(plugins []*klib.Plugin) error { + for _, plugin := range plugins { + if *plugin.Name == "acl" && *plugin.Enabled == true { + return nil } } - return "" + return fmt.Errorf("failed to find acl plugin is enabled and installed") } func (gc *Client) DiscoverAPIs() error { diff --git a/pkg/gateway/client_test.go b/pkg/gateway/client_test.go new file mode 100644 index 0000000..5cfe460 --- /dev/null +++ b/pkg/gateway/client_test.go @@ -0,0 +1,19 @@ +package gateway + +import ( + "testing" + + corecfg "github.com/Axway/agent-sdk/pkg/config" + config "github.com/Axway/agents-kong/pkg/config/discovery" +) + +func TestKongClient(t *testing.T) { + gatewayConfig := &config.KongGatewayConfig{ + AdminEndpoint: "http://localhost", + ProxyEndpoint: "http://localhost", + } + _ = config.AgentConfig{ + CentralCfg: corecfg.NewCentralConfig(corecfg.DiscoveryAgent), + KongGatewayCfg: gatewayConfig, + } +} diff --git a/pkg/processor/eventmapper.go b/pkg/processor/eventmapper.go index 3cda66d..61968f2 100644 --- a/pkg/processor/eventmapper.go +++ b/pkg/processor/eventmapper.go @@ -11,6 +11,7 @@ import ( "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/transaction" + sdkUtil "github.com/Axway/agent-sdk/pkg/transaction/util" "github.com/Axway/agent-sdk/pkg/util/log" ) @@ -157,12 +158,12 @@ func (m *EventMapper) createSummaryEvent(ktle KongTrafficLogEntry, teamID string ktle.Request.URI, ktle.Request.URL). SetDuration(ktle.Latencies.Request). - SetProxy(transaction.FormatProxyID(ktle.Route.ID), + SetProxy(sdkUtil.FormatProxyID(ktle.Route.ID), ktle.Service.Name, 1) if ktle.Consumer != nil { - builder.SetApplication(transaction.FormatApplicationID(ktle.Consumer.ID), ktle.Consumer.Username) + builder.SetApplication(sdkUtil.FormatApplicationID(ktle.Consumer.ID), ktle.Consumer.Username) } return builder.Build() diff --git a/pkg/subscription/provision.go b/pkg/subscription/provision.go index b8a0be8..c0a1584 100644 --- a/pkg/subscription/provision.go +++ b/pkg/subscription/provision.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/apic/provisioning" "github.com/Axway/agent-sdk/pkg/util" @@ -262,13 +263,13 @@ func createConsumer(kc *kong.Client, consumer kong.Consumer, ctx context.Context consumerResponse, err := kc.Consumers.Get(ctx, consumer.CustomID) if err != nil { log.Infof("Unable to find consumer application, Response from kong %s", err.Error()) - log.Infof("Creating new application with name %s", consumer.Username) + log.Infof("Creating new application with name %s", *consumer.Username) consumerResponse, err = kc.Consumers.Create(ctx, &consumer) if err != nil { return nil, err } } else { - log.Infof("Using the existing consumer %s", consumer.Username) + log.Infof("Using the existing consumer %s", *consumer.Username) } return consumerResponse, nil } From 59c9f29b6ffcb3a374a08bf1160b21432f020097 Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Mon, 30 Oct 2023 13:46:37 -0700 Subject: [PATCH 44/76] cleanup --- pkg/cmd/discovery/discoveryCmd.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/pkg/cmd/discovery/discoveryCmd.go b/pkg/cmd/discovery/discoveryCmd.go index 5e97d66..3b5c72e 100644 --- a/pkg/cmd/discovery/discoveryCmd.go +++ b/pkg/cmd/discovery/discoveryCmd.go @@ -36,8 +36,7 @@ func init() { // Callback that agent will call to process the execution func run() error { var err error - var stopChan chan struct{} - stopChan = make(chan struct{}) + stopChan := make(chan struct{}) gatewayClient, err := gateway.NewClient(agentConfig) if err != nil { @@ -48,7 +47,7 @@ func run() error { for { err = gatewayClient.DiscoverAPIs() if err != nil { - log.Error("error in processing: %s", err) + log.Errorf("error in processing: %s", err) stopChan <- struct{}{} } log.Infof("next poll in %s", agentConfig.CentralCfg.GetPollInterval()) @@ -56,11 +55,8 @@ func run() error { } }() - select { - case <-stopChan: - log.Info("Received signal to stop processing") - break - } + <-stopChan + log.Info("Received signal to stop processing") return err } From e90d3ad7c182e50874bd974d834f6f1514136764 Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Mon, 30 Oct 2023 13:46:45 -0700 Subject: [PATCH 45/76] update deps --- go.mod | 6 ------ go.sum | 1 - 2 files changed, 7 deletions(-) diff --git a/go.mod b/go.mod index 5e8629e..5be4d3d 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,7 @@ module github.com/Axway/agents-kong go 1.18 -//replace ( -// github.com/Axway/agent-sdk => target latest - -replace github.com/Axway/agent-sdk => /Users/rnatarajan/GolandProjects/agent-sdk require ( github.com/Axway/agent-sdk v1.1.58 github.com/elastic/beats/v7 v7.17.5 @@ -13,7 +9,6 @@ require ( github.com/kong/go-kong v0.46.0 github.com/sirupsen/logrus v1.9.3 github.com/tidwall/gjson v1.14.4 - gotest.tools v2.2.0+incompatible ) require ( @@ -184,5 +179,4 @@ replace ( github.com/getkin/kin-openapi => github.com/getkin/kin-openapi v0.67.0 k8s.io/apimachinery => k8s.io/apimachinery v0.21.1 k8s.io/client-go => k8s.io/client-go v0.21.1 - ) diff --git a/go.sum b/go.sum index 922f1e0..cbb6b1b 100644 --- a/go.sum +++ b/go.sum @@ -980,7 +980,6 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/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= 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= From 839ebf78d65325f62099d1114da29a19159adf80 Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Mon, 30 Oct 2023 13:46:52 -0700 Subject: [PATCH 46/76] update make --- Makefile | 74 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 61d246d..ace9a5a 100644 --- a/Makefile +++ b/Makefile @@ -1,29 +1,73 @@ -GO_VERSION=1.14.3 +.PHONY: all dep test build package + +WORKSPACE ?= $$(pwd) + +GO_PKG_LIST := $(shell go list ./... | grep -v /mock) PROJECT_NAME := agents-kong +export GOFLAGS := -mod=mod export GOPRIVATE=git.ecd.axway.org/apigov -tidy: go.mod +all: clean + @echo "Done" + +clean: + @rm -rf ./bin/ + @mkdir -p ./bin + @echo "Clean complete" + +resolve-dependencies: + @echo "Resolving go package dependencies" @go mod tidy + @echo "Package dependencies completed" + +dep: resolve-dependencies -download: tidy - @go mod download +dep-check: + @go mod verify -build-disc: - @go build -o bin/discovery ./cmd/discovery/main.go +${WORKSPACE}/discovery_agent: + @export time=`date +%Y%m%d%H%M%S` && \ + export version=`cat version` && \ + export commit_id=`cat commit_id` && \ + export CGO_ENABLED=0 && \ + export sdk_version=`go list -m github.com/Axway/agent-sdk | awk '{print $$2}' | awk -F'-' '{print substr($$1, 2)}'` && \ + go build -v -tags static_all \ + -ldflags="-X 'github.com/Axway/agent-sdk/pkg/cmd.BuildTime=$${time}' \ + -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildVersion=$${version}' \ + -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildCommitSha=$${commit_id}' \ + -X 'github.com/Axway/agent-sdk/pkg/cmd.SDKBuildVersion=$${sdk_version}' \ + -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildAgentName=KongDiscoveryAgent' \ + -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildAgentDescription=Kong Discovery Agent' \ + -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildDataPlaneType=Kong'" \ + -a -o ${WORKSPACE}/bin/discovery_agent ${WORKSPACE}/cmd/discovery/main.go -build-trace: - @go build -o bin/traceability ./cmd/traceability/main.go +build-da:dep ${WORKSPACE}/discovery_agent + @echo "Discovery Agent build completed" + +${WORKSPACE}/traceability_agent: + @export time=`date +%Y%m%d%H%M%S` && \ + export version=`cat version` && \ + export commit_id=`cat commit_id` && \ + export CGO_ENABLED=0 && \ + export sdk_version=`go list -m github.com/Axway/agent-sdk | awk '{print $$2}' | awk -F'-' '{print substr($$1, 2)}'` && \ + go build -v -tags static_all \ + -ldflags="-X 'github.com/Axway/agent-sdk/pkg/cmd.BuildTime=$${time}' \ + -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildVersion=$${version}' \ + -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildCommitSha=$${commit_id}' \ + -X 'github.com/Axway/agent-sdk/pkg/cmd.SDKBuildVersion=$${sdk_version}' \ + -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildAgentName=KongTraceabilityAgent' \ + -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildAgentDescription=Kong Traceability Agent' \ + -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildDataPlaneType=Kong'" \ + -a -o ${WORKSPACE}/bin/traceability_agent ${WORKSPACE}/cmd/traceability/main.go + + +build-ta: dep ${WORKSPACE}/traceability_agent + @echo "Traceability Agent build completed" run-disc: ./bin/discovery run-trace: - ./bin/traceability - -lint: - @golangci-lint run -v - -lint-fix: - @golangci-lint run -v --fix \ No newline at end of file + ./bin/traceability \ No newline at end of file From 548c2a2695206805ca1f71588abdb27fe1922857 Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Mon, 30 Oct 2023 13:47:10 -0700 Subject: [PATCH 47/76] change to remove errors --- pkg/processor/eventmapper.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/processor/eventmapper.go b/pkg/processor/eventmapper.go index 3cda66d..cb8a483 100644 --- a/pkg/processor/eventmapper.go +++ b/pkg/processor/eventmapper.go @@ -157,12 +157,12 @@ func (m *EventMapper) createSummaryEvent(ktle KongTrafficLogEntry, teamID string ktle.Request.URI, ktle.Request.URL). SetDuration(ktle.Latencies.Request). - SetProxy(transaction.FormatProxyID(ktle.Route.ID), + SetProxy(ktle.Route.ID, ktle.Service.Name, 1) if ktle.Consumer != nil { - builder.SetApplication(transaction.FormatApplicationID(ktle.Consumer.ID), ktle.Consumer.Username) + builder.SetApplication(ktle.Consumer.ID, ktle.Consumer.Username) } return builder.Build() From 61a3ac7c2dc67de3d67dac8f2d9f13d3d5c19c15 Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Mon, 30 Oct 2023 13:47:29 -0700 Subject: [PATCH 48/76] move application targets for provisioner to new file --- pkg/subscription/application.go | 65 +++++++++++++++++++++++++++ pkg/subscription/provision.go | 78 ++++++--------------------------- 2 files changed, 78 insertions(+), 65 deletions(-) create mode 100644 pkg/subscription/application.go diff --git a/pkg/subscription/application.go b/pkg/subscription/application.go new file mode 100644 index 0000000..6acd42a --- /dev/null +++ b/pkg/subscription/application.go @@ -0,0 +1,65 @@ +package subscription + +import ( + "context" + "errors" + + "github.com/Axway/agent-sdk/pkg/apic/provisioning" + "github.com/Axway/agent-sdk/pkg/util/log" + "github.com/Axway/agents-kong/pkg/common" + "github.com/kong/go-kong/kong" +) + +func (p provisioner) ApplicationRequestProvision(request provisioning.ApplicationRequest) provisioning.RequestStatus { + p.log.Info("provisioning application") + ctx := context.Background() + rs := provisioning.NewRequestStatusBuilder() + appName := request.GetManagedApplicationName() + if appName == "" { + return Failed(rs, notFound("managed application name")) + } + id := request.GetID() + consumer := kong.Consumer{ + CustomID: &id, + Username: &appName, + } + consumerResponse, err := createConsumer(p.client, consumer, ctx) + if err != nil { + return Failed(rs, errors.New("error creating consumer "+err.Error())) + } + // process application create + rs.AddProperty(common.AttrAppID, *consumerResponse.ID) + p.log. + WithField("appName", request.GetManagedApplicationName()). + Info("created application") + + return rs.Success() +} + +func (p provisioner) ApplicationRequestDeprovision(request provisioning.ApplicationRequest) provisioning.RequestStatus { + p.log.Info("de-provisioning application") + ctx := context.Background() + rs := provisioning.NewRequestStatusBuilder() + appID := request.GetApplicationDetailsValue(common.AttrAppID) + if appID == "" { + return Failed(rs, notFound(common.AttrAppID)) + } + consumerResponse, err := p.client.Consumers.Get(ctx, &appID) + if err != nil { + return Failed(rs, errors.New("error getting consumer details")) + } + if consumerResponse == nil { + log.Warnf("Application with id %s is already deleted", appID) + return rs.Success() + } + err = p.client.Consumers.Delete(ctx, &appID) + if err != nil { + return Failed(rs, errors.New("error deleting kong consumer")) + } + log.Infof("Application with Id %s deleted successfully on Kong", appID) + p.log. + WithField("appName", request.GetManagedApplicationName()). + WithField("appID", appID). + Info("removed application") + return rs.Success() +} diff --git a/pkg/subscription/provision.go b/pkg/subscription/provision.go index b8a0be8..27486f3 100644 --- a/pkg/subscription/provision.go +++ b/pkg/subscription/provision.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/apic/provisioning" "github.com/Axway/agent-sdk/pkg/util" @@ -29,30 +30,30 @@ type Handler interface { } type provisioner struct { - kc *kong.Client log logrus.FieldLogger + client *kong.Client handlers map[string]Handler } // NewProvisioner creates a type to implement the SDK Provisioning methods for handling subscriptions -func NewProvisioner(kc *kong.Client, log logrus.FieldLogger) { - logrus.Info("Registering provisioning callbacks") - logrus.Infof("Handlers : %d", len(constructors)) +func NewProvisioner(client *kong.Client, log logrus.FieldLogger) { + log.Info("Registering provisioning callbacks") + log.Infof("Handlers : %d", len(constructors)) handlers := make(map[string]Handler, len(constructors)) for _, c := range constructors { - h := c(kc) + h := c(client) h.Register() handlers[h.Name()] = h } provisioner := &provisioner{ // set supported subscription handlers - kc: kc, + client: client, handlers: handlers, log: log, } agent.RegisterProvisioner(provisioner) for _, handler := range handlers { - logrus.Infof("Registering authentication :%s", handler.Name()) + log.Infof("Registering authentication :%s", handler.Name()) handler.Register() } } @@ -68,59 +69,6 @@ func (p provisioner) CredentialUpdate(request provisioning.CredentialRequest) (p return Failed(provisioning.NewRequestStatusBuilder(), errors.New(errorMsg)), nil } -func (p provisioner) ApplicationRequestProvision(request provisioning.ApplicationRequest) provisioning.RequestStatus { - p.log.Info("provisioning application") - ctx := context.Background() - rs := provisioning.NewRequestStatusBuilder() - appName := request.GetManagedApplicationName() - if appName == "" { - return Failed(rs, notFound("managed application name")) - } - id := request.GetID() - consumer := kong.Consumer{ - CustomID: &id, - Username: &appName, - } - consumerResponse, err := createConsumer(p.kc, consumer, ctx) - if err != nil { - return Failed(rs, errors.New("error creating consumer "+err.Error())) - } - // process application create - rs.AddProperty(common.AttrAppID, *consumerResponse.ID) - p.log. - WithField("appName", request.GetManagedApplicationName()). - Info("created application") - - return rs.Success() -} - -func (p provisioner) ApplicationRequestDeprovision(request provisioning.ApplicationRequest) provisioning.RequestStatus { - p.log.Info("de-provisioning application") - ctx := context.Background() - rs := provisioning.NewRequestStatusBuilder() - appID := request.GetApplicationDetailsValue(common.AttrAppID) - if appID == "" { - return Failed(rs, notFound(common.AttrAppID)) - } - consumerResponse, err := p.kc.Consumers.Get(ctx, &appID) - if err != nil { - return Failed(rs, errors.New("error getting consumer details")) - } - if consumerResponse == nil { - log.Warnf("Application with id %s is already deleted", appID) - return rs.Success() - } - err = p.kc.Consumers.Delete(ctx, &appID) - if err != nil { - return Failed(rs, errors.New("error deleting kong consumer")) - } - log.Infof("Application with Id %s deleted successfully on Kong", appID) - p.log. - WithField("appName", request.GetManagedApplicationName()). - WithField("appID", appID). - Info("removed application") - return rs.Success() -} func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) (provisioning.RequestStatus, provisioning.AccessData) { p.log.Info("provisioning access request") agentTag := "amplify-agent" @@ -144,13 +92,13 @@ func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) Username: &appName, } var err error - consumerResponse, err := createConsumer(p.kc, consumer, ctx) + consumerResponse, err := createConsumer(p.client, consumer, ctx) if err != nil { return Failed(rs, errors.New("error creating kong consumer")), nil } kongApplicationId = *consumerResponse.ID } - plugins := kutil.Plugins{PluginLister: p.kc.Plugins} + plugins := kutil.Plugins{PluginLister: p.client.Plugins} ep, err := plugins.GetEffectivePlugins(routeId, serviceId) if err != nil { return Failed(rs, fmt.Errorf("failed to list route plugins: %w", err)), nil @@ -158,14 +106,14 @@ func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) plugin, ok := ep["acl"] if !ok { log.Infof("ACL Plugin is not configured on route / service %s", serviceId) - _, err := p.kc.Plugins.CreateForService(ctx, &serviceId, plugin) + _, err := p.client.Plugins.CreateForService(ctx, &serviceId, plugin) if err != nil { return Failed(rs, fmt.Errorf("failed to add ACL pluing to service: %w", err)), nil } } group := common.AclGroup consumerTags := []*string{&agentTag} - _, err = p.kc.ACLs.Create(ctx, &kongApplicationId, &kong.ACLGroup{Group: &group, Tags: consumerTags}) + _, err = p.client.ACLs.Create(ctx, &kongApplicationId, &kong.ACLGroup{Group: &group, Tags: consumerTags}) if err != nil { return Failed(rs, fmt.Errorf("failed to add acl group on consumer: %w", err)), nil } @@ -215,7 +163,7 @@ func (p provisioner) AccessRequestDeprovision(request provisioning.AccessRequest return Failed(rs, notFound(common.AttrAppID)) } group := common.AclGroup - err := p.kc.ACLs.Delete(ctx, &kongConsumerId, &group) + err := p.client.ACLs.Delete(ctx, &kongConsumerId, &group) if err != nil { return Failed(rs, fmt.Errorf("failed to remove acl group on consumer: %w", err)) } From f1eca6e9abbb81a86c93220a194034518a2a0266 Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Mon, 30 Oct 2023 15:57:30 -0700 Subject: [PATCH 49/76] application provisioning updates and other cleanup --- pkg/gateway/client.go | 11 ++- pkg/kong/kongclient.go | 6 ++ pkg/kong/provisioning.go | 23 ++++++ pkg/subscription/application.go | 23 +++--- pkg/subscription/auth/oauth2/oauth2.go | 1 + pkg/subscription/provision.go | 97 ++++++++++---------------- 6 files changed, 81 insertions(+), 80 deletions(-) create mode 100644 pkg/kong/provisioning.go diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 7802364..50b057d 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -4,12 +4,13 @@ import ( "context" "crypto/sha256" "fmt" + "net/http" + "sync" + "github.com/Axway/agent-sdk/pkg/apic/provisioning" "github.com/Axway/agents-kong/pkg/common" "github.com/Axway/agents-kong/pkg/subscription" "github.com/sirupsen/logrus" - "net/http" - "sync" "github.com/Axway/agents-kong/pkg/kong/specmanager" "github.com/Axway/agents-kong/pkg/kong/specmanager/devportal" @@ -45,9 +46,7 @@ func NewClient(agentConfig config.AgentConfig) (*Client, error) { specmanager.AddSource(localdir.NewSpecificationSource(agentConfig.KongGatewayCfg.SpecHomePath)) } daCache := cache.New() - logger := logrus.WithFields(logrus.Fields{ - "component": "agent", - }) + logger := log.NewFieldLogger().WithField("component", "agent") plugins, err := kongClient.Plugins.ListAll(context.Background()) if err != nil { @@ -64,7 +63,7 @@ func NewClient(agentConfig config.AgentConfig) (*Client, error) { } } } - subscription.NewProvisioner(kongClient.Client, logger) + subscription.NewProvisioner(kongClient, logger) return &Client{ centralCfg: agentConfig.CentralCfg, kongGatewayCfg: kongGatewayConfig, diff --git a/pkg/kong/kongclient.go b/pkg/kong/kongclient.go index fa44d4e..198cf72 100644 --- a/pkg/kong/kongclient.go +++ b/pkg/kong/kongclient.go @@ -7,6 +7,7 @@ import ( "io" "net/http" + "github.com/Axway/agent-sdk/pkg/util/log" "github.com/Axway/agents-kong/pkg/kong/specmanager" config "github.com/Axway/agents-kong/pkg/config/discovery" @@ -15,6 +16,9 @@ import ( ) type KongAPIClient interface { + // Provisioning + CreateConsumer(ctx context.Context, id, name string) (*klib.Consumer, error) + ListServices(ctx context.Context) ([]*klib.Service, error) ListRoutesForService(ctx context.Context, serviceId string) ([]*klib.Route, error) GetSpecForService(ctx context.Context, serviceId string) (*specmanager.KongServiceSpec, error) @@ -23,6 +27,7 @@ type KongAPIClient interface { type KongClient struct { *klib.Client + logger log.FieldLogger baseClient DoRequest kongAdminEndpoint string } @@ -44,6 +49,7 @@ func NewKongClient(baseClient *http.Client, kongConfig *config.KongGatewayConfig } return &KongClient{ Client: baseKongClient, + logger: log.NewFieldLogger().WithComponent("apiClient").WithPackage("kong"), baseClient: baseClient, kongAdminEndpoint: kongConfig.AdminEndpoint, }, nil diff --git a/pkg/kong/provisioning.go b/pkg/kong/provisioning.go new file mode 100644 index 0000000..dd610a6 --- /dev/null +++ b/pkg/kong/provisioning.go @@ -0,0 +1,23 @@ +package kong + +import ( + "context" + + klib "github.com/kong/go-kong/kong" +) + +func (k KongClient) CreateConsumer(ctx context.Context, id, name string) (*klib.Consumer, error) { + // validate that the consumer does not already exist + log := k.logger.WithField("consumerID", id).WithField("consumerName", name) + consumer, err := k.Consumers.Get(ctx, &id) + if err == nil { + log.Infof("found existing consumer") + return consumer, err + } + + log.Infof("creating new application") + return k.Consumers.Create(ctx, &klib.Consumer{ + CustomID: &id, + Username: &name, + }) +} diff --git a/pkg/subscription/application.go b/pkg/subscription/application.go index 6acd42a..a08ecbd 100644 --- a/pkg/subscription/application.go +++ b/pkg/subscription/application.go @@ -7,29 +7,24 @@ import ( "github.com/Axway/agent-sdk/pkg/apic/provisioning" "github.com/Axway/agent-sdk/pkg/util/log" "github.com/Axway/agents-kong/pkg/common" - "github.com/kong/go-kong/kong" ) func (p provisioner) ApplicationRequestProvision(request provisioning.ApplicationRequest) provisioning.RequestStatus { - p.log.Info("provisioning application") + p.logger.Info("provisioning application") ctx := context.Background() rs := provisioning.NewRequestStatusBuilder() appName := request.GetManagedApplicationName() if appName == "" { return Failed(rs, notFound("managed application name")) } - id := request.GetID() - consumer := kong.Consumer{ - CustomID: &id, - Username: &appName, - } - consumerResponse, err := createConsumer(p.client, consumer, ctx) + consumer, err := p.client.CreateConsumer(ctx, request.GetID(), appName) if err != nil { return Failed(rs, errors.New("error creating consumer "+err.Error())) } + // process application create - rs.AddProperty(common.AttrAppID, *consumerResponse.ID) - p.log. + rs.AddProperty(common.AttrAppID, *consumer.ID) + p.logger. WithField("appName", request.GetManagedApplicationName()). Info("created application") @@ -37,14 +32,14 @@ func (p provisioner) ApplicationRequestProvision(request provisioning.Applicatio } func (p provisioner) ApplicationRequestDeprovision(request provisioning.ApplicationRequest) provisioning.RequestStatus { - p.log.Info("de-provisioning application") + p.logger.Info("de-provisioning application") ctx := context.Background() rs := provisioning.NewRequestStatusBuilder() appID := request.GetApplicationDetailsValue(common.AttrAppID) if appID == "" { return Failed(rs, notFound(common.AttrAppID)) } - consumerResponse, err := p.client.Consumers.Get(ctx, &appID) + consumerResponse, err := p.kc.Consumers.Get(ctx, &appID) if err != nil { return Failed(rs, errors.New("error getting consumer details")) } @@ -52,12 +47,12 @@ func (p provisioner) ApplicationRequestDeprovision(request provisioning.Applicat log.Warnf("Application with id %s is already deleted", appID) return rs.Success() } - err = p.client.Consumers.Delete(ctx, &appID) + err = p.kc.Consumers.Delete(ctx, &appID) if err != nil { return Failed(rs, errors.New("error deleting kong consumer")) } log.Infof("Application with Id %s deleted successfully on Kong", appID) - p.log. + p.logger. WithField("appName", request.GetManagedApplicationName()). WithField("appID", appID). Info("removed application") diff --git a/pkg/subscription/auth/oauth2/oauth2.go b/pkg/subscription/auth/oauth2/oauth2.go index d8b38c3..5a394f9 100644 --- a/pkg/subscription/auth/oauth2/oauth2.go +++ b/pkg/subscription/auth/oauth2/oauth2.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/apic/provisioning" "github.com/Axway/agents-kong/pkg/common" diff --git a/pkg/subscription/provision.go b/pkg/subscription/provision.go index 27486f3..6d099d3 100644 --- a/pkg/subscription/provision.go +++ b/pkg/subscription/provision.go @@ -5,19 +5,21 @@ import ( "errors" "fmt" + kongSDK "github.com/kong/go-kong/kong" + "github.com/sirupsen/logrus" + "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/apic/provisioning" - "github.com/Axway/agent-sdk/pkg/util" + sdkUtil "github.com/Axway/agent-sdk/pkg/util" "github.com/Axway/agent-sdk/pkg/util/log" + "github.com/Axway/agents-kong/pkg/common" - kutil "github.com/Axway/agents-kong/pkg/kong" - "github.com/kong/go-kong/kong" - "github.com/sirupsen/logrus" + "github.com/Axway/agents-kong/pkg/kong" ) -var constructors []func(*kong.Client) Handler +var constructors []func(*kongSDK.Client) Handler -func Add(constructor func(*kong.Client) Handler) { +func Add(constructor func(*kongSDK.Client) Handler) { constructors = append(constructors, constructor) } @@ -30,18 +32,19 @@ type Handler interface { } type provisioner struct { - log logrus.FieldLogger - client *kong.Client + logger log.FieldLogger + client kong.KongAPIClient + kc *kongSDK.Client handlers map[string]Handler } // NewProvisioner creates a type to implement the SDK Provisioning methods for handling subscriptions -func NewProvisioner(client *kong.Client, log logrus.FieldLogger) { - log.Info("Registering provisioning callbacks") - log.Infof("Handlers : %d", len(constructors)) +func NewProvisioner(client kong.KongAPIClient, logger log.FieldLogger) { + logger.Info("Registering provisioning callbacks") + logger.Infof("Handlers : %d", len(constructors)) handlers := make(map[string]Handler, len(constructors)) for _, c := range constructors { - h := c(client) + h := c(client.(*kong.KongClient).Client) h.Register() handlers[h.Name()] = h } @@ -49,7 +52,7 @@ func NewProvisioner(client *kong.Client, log logrus.FieldLogger) { // set supported subscription handlers client: client, handlers: handlers, - log: log, + logger: logger, } agent.RegisterProvisioner(provisioner) for _, handler := range handlers { @@ -59,7 +62,7 @@ func NewProvisioner(client *kong.Client, log logrus.FieldLogger) { } func (p provisioner) CredentialUpdate(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { - p.log.Info("provisioning credentials update") + p.logger.Info("provisioning credentials update") credentialType := request.GetCredentialType() if h, ok := p.handlers[credentialType]; ok { return h.UpdateCredential(request) @@ -70,13 +73,13 @@ func (p provisioner) CredentialUpdate(request provisioning.CredentialRequest) (p } func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) (provisioning.RequestStatus, provisioning.AccessData) { - p.log.Info("provisioning access request") + p.logger.Info("provisioning access request") agentTag := "amplify-agent" ctx := context.Background() rs := provisioning.NewRequestStatusBuilder() instDetails := request.GetInstanceDetails() - serviceId := util.ToString(instDetails[common.AttrServiceId]) - routeId := util.ToString(instDetails[common.AttrRouteId]) + serviceId := sdkUtil.ToString(instDetails[common.AttrServiceId]) + routeId := sdkUtil.ToString(instDetails[common.AttrRouteId]) if serviceId == "" { return Failed(rs, notFound(common.AttrServiceId)), nil } @@ -85,20 +88,9 @@ func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) } kongApplicationId := request.GetApplicationDetailsValue(common.AttrAppID) if kongApplicationId == "" { - // Using the existing application - appName := request.GetApplicationName() - consumer := kong.Consumer{ - CustomID: &kongApplicationId, - Username: &appName, - } - var err error - consumerResponse, err := createConsumer(p.client, consumer, ctx) - if err != nil { - return Failed(rs, errors.New("error creating kong consumer")), nil - } - kongApplicationId = *consumerResponse.ID + return Failed(rs, fmt.Errorf("kong application id not set")), nil } - plugins := kutil.Plugins{PluginLister: p.client.Plugins} + plugins := kong.Plugins{PluginLister: p.kc.Plugins} ep, err := plugins.GetEffectivePlugins(routeId, serviceId) if err != nil { return Failed(rs, fmt.Errorf("failed to list route plugins: %w", err)), nil @@ -106,14 +98,14 @@ func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) plugin, ok := ep["acl"] if !ok { log.Infof("ACL Plugin is not configured on route / service %s", serviceId) - _, err := p.client.Plugins.CreateForService(ctx, &serviceId, plugin) + _, err := p.kc.Plugins.CreateForService(ctx, &serviceId, plugin) if err != nil { return Failed(rs, fmt.Errorf("failed to add ACL pluing to service: %w", err)), nil } } group := common.AclGroup consumerTags := []*string{&agentTag} - _, err = p.client.ACLs.Create(ctx, &kongApplicationId, &kong.ACLGroup{Group: &group, Tags: consumerTags}) + _, err = p.kc.ACLs.Create(ctx, &kongApplicationId, &kongSDK.ACLGroup{Group: &group, Tags: consumerTags}) if err != nil { return Failed(rs, fmt.Errorf("failed to add acl group on consumer: %w", err)), nil } @@ -124,12 +116,12 @@ func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) planName := amplifyQuota.GetPlanName() planDesc := amplifyQuota.GetPlanName() quotaLimit := int(amplifyQuota.GetLimit()) - p.log.Info(" Plan name :%s, Plan Description :%s Quota Limit: %s", planName, planDesc, quotaLimit) - config := kong.Configuration{ + p.logger.Info(" Plan name :%s, Plan Description :%s Quota Limit: %s", planName, planDesc, quotaLimit) + config := kongSDK.Configuration{ "limit": []interface{}{quotaLimit}, "policy": "local", } - p.log.Info("%v", config) + p.logger.Info("%v", config) //err := addRateLimit(p.kc, ctx, config, "") //if err != nil { // return nil, nil @@ -137,19 +129,19 @@ func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) //amplifyQuota.GetInterval(). } - p.log. + p.logger. WithField("api", serviceId). WithField("app", request.GetApplicationName()). Info("granted access") return rs.Success(), nil } func (p provisioner) AccessRequestDeprovision(request provisioning.AccessRequest) provisioning.RequestStatus { - p.log.Info("deprovisioning access request") + p.logger.Info("deprovisioning access request") ctx := context.Background() rs := provisioning.NewRequestStatusBuilder() instDetails := request.GetInstanceDetails() - serviceId := util.ToString(instDetails[common.AttrServiceId]) - routeId := util.ToString(instDetails[common.AttrRouteId]) + serviceId := sdkUtil.ToString(instDetails[common.AttrServiceId]) + routeId := sdkUtil.ToString(instDetails[common.AttrRouteId]) if serviceId == "" { return Failed(rs, notFound(common.AttrServiceId)) } @@ -163,11 +155,11 @@ func (p provisioner) AccessRequestDeprovision(request provisioning.AccessRequest return Failed(rs, notFound(common.AttrAppID)) } group := common.AclGroup - err := p.client.ACLs.Delete(ctx, &kongConsumerId, &group) + err := p.kc.ACLs.Delete(ctx, &kongConsumerId, &group) if err != nil { return Failed(rs, fmt.Errorf("failed to remove acl group on consumer: %w", err)) } - p.log. + p.logger. WithField("api", serviceId). WithField("app", request.GetApplicationName()). Info("removed access") @@ -175,7 +167,7 @@ func (p provisioner) AccessRequestDeprovision(request provisioning.AccessRequest } func (p provisioner) CredentialProvision(request provisioning.CredentialRequest) (provisioning.RequestStatus, provisioning.Credential) { - p.log.Info("provisioning credentials") + p.logger.Info("provisioning credentials") credentialType := request.GetCredentialType() if h, ok := p.handlers[credentialType]; ok { return h.CreateCredential(request) @@ -185,7 +177,7 @@ func (p provisioner) CredentialProvision(request provisioning.CredentialRequest) return Failed(provisioning.NewRequestStatusBuilder(), errors.New(errorMsg)), nil } func (p provisioner) CredentialDeprovision(request provisioning.CredentialRequest) provisioning.RequestStatus { - p.log.Info("de_provisioning credentials") + p.logger.Info("de_provisioning credentials") credentialType := request.GetCredentialType() if h, ok := p.handlers[credentialType]; ok { return h.DeleteCredential(request) @@ -206,21 +198,6 @@ func notFound(msg string) error { return fmt.Errorf("%s not found", msg) } -func createConsumer(kc *kong.Client, consumer kong.Consumer, ctx context.Context) (*kong.Consumer, error) { - consumerResponse, err := kc.Consumers.Get(ctx, consumer.CustomID) - if err != nil { - log.Infof("Unable to find consumer application, Response from kong %s", err.Error()) - log.Infof("Creating new application with name %s", consumer.Username) - consumerResponse, err = kc.Consumers.Create(ctx, &consumer) - if err != nil { - return nil, err - } - } else { - log.Infof("Using the existing consumer %s", consumer.Username) - } - return consumerResponse, nil -} - func GetCorsSchemaPropertyBuilder() provisioning.PropertyBuilder { return provisioning.NewSchemaPropertyBuilder(). SetName(common.CorsField). @@ -240,9 +217,9 @@ func GetProvisionKeyPropertyBuilder() provisioning.PropertyBuilder { IsString() } -//func addRateLimit(kc *kong.Client, ctx context.Context, config map[string]interface{}, serviceId string) error { +//func addRateLimit(kc *kongSDK.Client, ctx context.Context, config map[string]interface{}, serviceId string) error { // pluginName := "rate-limiting" -// rateLimitPlugin := kong.Plugin{ +// rateLimitPlugin := kongSDK.Plugin{ // Name: &pluginName, // Config: config, // } From def55701276f95ae17aa5ef918cf91d847925203 Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Tue, 31 Oct 2023 12:44:06 -0700 Subject: [PATCH 50/76] deprovisioning update --- pkg/kong/kongclient.go | 3 +- pkg/kong/provisioning.go | 20 +++++++++++-- pkg/subscription/application.go | 52 ++++++++++++++++++--------------- 3 files changed, 49 insertions(+), 26 deletions(-) diff --git a/pkg/kong/kongclient.go b/pkg/kong/kongclient.go index 198cf72..502399b 100644 --- a/pkg/kong/kongclient.go +++ b/pkg/kong/kongclient.go @@ -18,6 +18,7 @@ import ( type KongAPIClient interface { // Provisioning CreateConsumer(ctx context.Context, id, name string) (*klib.Consumer, error) + DeleteConsumer(ctx context.Context, id string) error ListServices(ctx context.Context) ([]*klib.Service, error) ListRoutesForService(ctx context.Context, serviceId string) ([]*klib.Route, error) @@ -49,7 +50,7 @@ func NewKongClient(baseClient *http.Client, kongConfig *config.KongGatewayConfig } return &KongClient{ Client: baseKongClient, - logger: log.NewFieldLogger().WithComponent("apiClient").WithPackage("kong"), + logger: log.NewFieldLogger().WithComponent("KongClient").WithPackage("kong"), baseClient: baseClient, kongAdminEndpoint: kongConfig.AdminEndpoint, }, nil diff --git a/pkg/kong/provisioning.go b/pkg/kong/provisioning.go index dd610a6..6c7cccd 100644 --- a/pkg/kong/provisioning.go +++ b/pkg/kong/provisioning.go @@ -11,13 +11,29 @@ func (k KongClient) CreateConsumer(ctx context.Context, id, name string) (*klib. log := k.logger.WithField("consumerID", id).WithField("consumerName", name) consumer, err := k.Consumers.Get(ctx, &id) if err == nil { - log.Infof("found existing consumer") + log.Debug("found existing consumer") return consumer, err } - log.Infof("creating new application") + log.Debug("creating new consumer") return k.Consumers.Create(ctx, &klib.Consumer{ CustomID: &id, Username: &name, }) } + +func (k KongClient) DeleteConsumer(ctx context.Context, id string) error { + // validate that the consumer does not already exist + log := k.logger.WithField("consumerID", id) + consumer, err := k.Consumers.Get(ctx, &id) + if err != nil { + return err + } + if consumer == nil { + log.Debug("consumer does not exist") + return nil + } + + log.Debug("deleting consumer") + return k.Consumers.Delete(ctx, &id) +} diff --git a/pkg/subscription/application.go b/pkg/subscription/application.go index a08ecbd..3aeb295 100644 --- a/pkg/subscription/application.go +++ b/pkg/subscription/application.go @@ -5,56 +5,62 @@ import ( "errors" "github.com/Axway/agent-sdk/pkg/apic/provisioning" - "github.com/Axway/agent-sdk/pkg/util/log" "github.com/Axway/agents-kong/pkg/common" ) +const ( + logFieldAppID = "appID" + logFieldAppName = "appName" +) + func (p provisioner) ApplicationRequestProvision(request provisioning.ApplicationRequest) provisioning.RequestStatus { - p.logger.Info("provisioning application") + log := p.logger + log.Info("provisioning application") + ctx := context.Background() rs := provisioning.NewRequestStatusBuilder() + appName := request.GetManagedApplicationName() if appName == "" { + log.Error("could not find the managed application name on the resource") return Failed(rs, notFound("managed application name")) } - consumer, err := p.client.CreateConsumer(ctx, request.GetID(), appName) + appID := request.GetID() + log = log.WithField(logFieldAppID, appID).WithField(logFieldAppName, appName) + + consumer, err := p.client.CreateConsumer(ctx, appID, appName) if err != nil { - return Failed(rs, errors.New("error creating consumer "+err.Error())) + log.WithError(err).Error("error creating kong consumer") + return Failed(rs, errors.New("could not create a new consumer in kong")) } // process application create rs.AddProperty(common.AttrAppID, *consumer.ID) - p.logger. - WithField("appName", request.GetManagedApplicationName()). - Info("created application") + log.Info("created application") return rs.Success() } func (p provisioner) ApplicationRequestDeprovision(request provisioning.ApplicationRequest) provisioning.RequestStatus { - p.logger.Info("de-provisioning application") + log := p.logger + log.Info("deprovisioning application") + ctx := context.Background() rs := provisioning.NewRequestStatusBuilder() + appID := request.GetApplicationDetailsValue(common.AttrAppID) if appID == "" { + log.Error("could not find the consumer id on the managed application resource") return Failed(rs, notFound(common.AttrAppID)) } - consumerResponse, err := p.kc.Consumers.Get(ctx, &appID) - if err != nil { - return Failed(rs, errors.New("error getting consumer details")) - } - if consumerResponse == nil { - log.Warnf("Application with id %s is already deleted", appID) - return rs.Success() - } - err = p.kc.Consumers.Delete(ctx, &appID) + log = log.WithField(logFieldAppID, appID).WithField(logFieldAppName, request.GetManagedApplicationName()) + + err := p.client.DeleteConsumer(ctx, appID) if err != nil { - return Failed(rs, errors.New("error deleting kong consumer")) + log.WithError(err).Error("error deleting kong consumer") + return Failed(rs, errors.New("could not remove consumer in kong")) } - log.Infof("Application with Id %s deleted successfully on Kong", appID) - p.logger. - WithField("appName", request.GetManagedApplicationName()). - WithField("appID", appID). - Info("removed application") + p.logger.Info("removed application") + return rs.Success() } From 90e3c369c3843074c805ba6d7663cf990215ec9e Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Tue, 31 Oct 2023 14:16:00 -0700 Subject: [PATCH 51/76] add tests for provisioning --- go.mod | 2 + pkg/kong/provisioning.go | 9 +- pkg/kong/provisioning_test.go | 182 ++++++++++++++++++++++++++++++++++ 3 files changed, 187 insertions(+), 6 deletions(-) create mode 100644 pkg/kong/provisioning_test.go diff --git a/go.mod b/go.mod index 5be4d3d..e5cd624 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/google/uuid v1.3.0 github.com/kong/go-kong v0.46.0 github.com/sirupsen/logrus v1.9.3 + github.com/stretchr/testify v1.8.4 github.com/tidwall/gjson v1.14.4 ) @@ -109,6 +110,7 @@ require ( github.com/pelletier/go-toml/v2 v2.0.2 // indirect github.com/pierrec/lz4 v2.6.0+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/procfs v0.7.3 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect diff --git a/pkg/kong/provisioning.go b/pkg/kong/provisioning.go index 6c7cccd..e631330 100644 --- a/pkg/kong/provisioning.go +++ b/pkg/kong/provisioning.go @@ -23,14 +23,11 @@ func (k KongClient) CreateConsumer(ctx context.Context, id, name string) (*klib. } func (k KongClient) DeleteConsumer(ctx context.Context, id string) error { - // validate that the consumer does not already exist + // validate that the consumer has not already been removed log := k.logger.WithField("consumerID", id) - consumer, err := k.Consumers.Get(ctx, &id) + _, err := k.Consumers.Get(ctx, &id) if err != nil { - return err - } - if consumer == nil { - log.Debug("consumer does not exist") + log.Debug("could not get consumer") return nil } diff --git a/pkg/kong/provisioning_test.go b/pkg/kong/provisioning_test.go new file mode 100644 index 0000000..b71e955 --- /dev/null +++ b/pkg/kong/provisioning_test.go @@ -0,0 +1,182 @@ +package kong + +import ( + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + klib "github.com/kong/go-kong/kong" + "github.com/stretchr/testify/assert" + + config "github.com/Axway/agents-kong/pkg/config/discovery" +) + +type response struct { + code int + dataIface interface{} + data []byte +} + +func createClient(responses map[string]map[string]response) KongAPIClient { + s := httptest.NewServer(http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + if pathRes, foundPath := responses[req.URL.Path]; foundPath { + if res, found := pathRes[req.Method]; found { + resp.WriteHeader(res.code) + if res.dataIface != nil { + data, _ := json.Marshal(res.dataIface) + resp.Write(data) + } else { + resp.Write(res.data) + } + return + } + } + })) + cfg := &config.KongGatewayConfig{ + AdminEndpoint: s.URL, + } + client, _ := NewKongClient(&http.Client{}, cfg) + return client +} + +func TestCreateConsumer(t *testing.T) { + testCases := map[string]struct { + expectErr bool + id string + name string + responses map[string]map[string]response + }{ + "find existing consumer": { + expectErr: false, + id: "existingID", + name: "existingName", + responses: map[string]map[string]response{ + "/consumers/" + "existingID": { + http.MethodGet: { + code: http.StatusOK, + dataIface: &klib.Consumer{ + ID: klib.String("existingID"), + Username: klib.String("existingName"), + }, + }, + }, + }, + }, + "create new consumer": { + expectErr: false, + id: "nameID", + name: "newName", + responses: map[string]map[string]response{ + "/consumers/" + "nameID": { + http.MethodGet: { + code: http.StatusNotFound, + }, + }, + "/consumers": { + http.MethodPost: { + code: http.StatusCreated, + dataIface: &klib.Consumer{ + ID: klib.String("nameID"), + Username: klib.String("newName"), + }, + }, + }, + }, + }, + "create new consumer error": { + expectErr: true, + id: "nameID", + name: "newName", + responses: map[string]map[string]response{ + "/consumers/" + "nameID": { + http.MethodGet: { + code: http.StatusNotFound, + }, + }, + "/consumers": { + http.MethodPost: { + code: http.StatusBadRequest, + }, + }, + }, + }, + } + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + client := createClient(tc.responses) + c, err := client.CreateConsumer(context.TODO(), tc.id, tc.name) + if tc.expectErr { + assert.NotNil(t, err) + return + } + assert.Nil(t, err) + assert.Equal(t, tc.id, *c.ID) + assert.Equal(t, tc.name, *c.Username) + }) + } +} + +func TestDeleteConsumer(t *testing.T) { + testCases := map[string]struct { + expectErr bool + responses map[string]map[string]response + }{ + "consumer does not exist": { + expectErr: false, + responses: map[string]map[string]response{ + "/consumers/" + "id": { + http.MethodGet: { + code: http.StatusNotFound, + }, + }, + }, + }, + "delete consumer": { + expectErr: false, + responses: map[string]map[string]response{ + "/consumers/" + "id": { + http.MethodGet: { + code: http.StatusOK, + dataIface: &klib.Consumer{ + ID: klib.String("id"), + Username: klib.String("name"), + }, + }, + http.MethodDelete: { + code: http.StatusAccepted, + }, + }, + }, + }, + "delete consumer error": { + expectErr: true, + responses: map[string]map[string]response{ + "/consumers/" + "id": { + http.MethodGet: { + code: http.StatusOK, + dataIface: &klib.Consumer{ + ID: klib.String("id"), + Username: klib.String("name"), + }, + }, + http.MethodDelete: { + code: http.StatusBadRequest, + }, + }, + }, + }, + } + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + client := createClient(tc.responses) + err := client.DeleteConsumer(context.TODO(), "id") + if tc.expectErr { + assert.NotNil(t, err) + return + } + assert.Nil(t, err) + }) + } +} From 619dc8e2cb8260dda3c0473a2796ba003122def7 Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Tue, 31 Oct 2023 14:38:47 -0700 Subject: [PATCH 52/76] add test target and fix test errors --- Makefile | 4 ++++ pkg/beater/custom_beater.go | 14 +++++--------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index ace9a5a..c357d37 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,10 @@ export GOPRIVATE=git.ecd.axway.org/apigov all: clean @echo "Done" +test: dep + @go vet ${GO_PKG_LIST} + @go test -race -v -short -coverprofile=${WORKSPACE}/gocoverage.out -count=1 ${GO_PKG_LIST} + clean: @rm -rf ./bin/ @mkdir -p ./bin diff --git a/pkg/beater/custom_beater.go b/pkg/beater/custom_beater.go index 11e1af8..0a75495 100644 --- a/pkg/beater/custom_beater.go +++ b/pkg/beater/custom_beater.go @@ -51,7 +51,7 @@ func (bt *customLogBeater) Run(b *beat.Beat) error { return err } - http.HandleFunc(fmt.Sprintf("%s", traceabilityconfig.GetAgentConfig().HttpLogPluginConfig.Path), + http.HandleFunc(traceabilityconfig.GetAgentConfig().HttpLogPluginConfig.Path, func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { w.WriteHeader(http.StatusMethodNotAllowed) @@ -62,7 +62,7 @@ func (bt *customLogBeater) Run(b *beat.Beat) error { defer r.Body.Close() if err != nil { - fmt.Errorf("Error while reading request body: %s", err) + logp.Error(fmt.Errorf("error while reading request body: %s", err)) } w.WriteHeader(200) @@ -74,17 +74,13 @@ func (bt *customLogBeater) Run(b *beat.Beat) error { go func() { if err := http.ListenAndServe(fmt.Sprintf(":%d", traceabilityconfig.GetAgentConfig().HttpLogPluginConfig.Port), nil); err != nil { - log.Fatal("Unable to start the HTTP Server: %s", err) + log.Fatalf("Unable to start the HTTP Server: %s", err) } fmt.Printf("Started HTTP server on port %d to receive request logs", traceabilityconfig.GetAgentConfig().HttpLogPluginConfig.Port) }() - for { - select { - case <-bt.done: - return nil - } - } + <-bt.done + return nil } // Stop stops kong_traceability_agent. From 40617909e4ba91d1832bca5bad3cb0663da22a4e Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Tue, 31 Oct 2023 14:38:57 -0700 Subject: [PATCH 53/76] use klib string --- pkg/kong/provisioning.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/kong/provisioning.go b/pkg/kong/provisioning.go index e631330..90a49ee 100644 --- a/pkg/kong/provisioning.go +++ b/pkg/kong/provisioning.go @@ -9,7 +9,7 @@ import ( func (k KongClient) CreateConsumer(ctx context.Context, id, name string) (*klib.Consumer, error) { // validate that the consumer does not already exist log := k.logger.WithField("consumerID", id).WithField("consumerName", name) - consumer, err := k.Consumers.Get(ctx, &id) + consumer, err := k.Consumers.Get(ctx, klib.String(id)) if err == nil { log.Debug("found existing consumer") return consumer, err @@ -17,20 +17,20 @@ func (k KongClient) CreateConsumer(ctx context.Context, id, name string) (*klib. log.Debug("creating new consumer") return k.Consumers.Create(ctx, &klib.Consumer{ - CustomID: &id, - Username: &name, + CustomID: klib.String(id), + Username: klib.String(name), }) } func (k KongClient) DeleteConsumer(ctx context.Context, id string) error { // validate that the consumer has not already been removed log := k.logger.WithField("consumerID", id) - _, err := k.Consumers.Get(ctx, &id) + _, err := k.Consumers.Get(ctx, klib.String(id)) if err != nil { log.Debug("could not get consumer") return nil } log.Debug("deleting consumer") - return k.Consumers.Delete(ctx, &id) + return k.Consumers.Delete(ctx, klib.String(id)) } From aabd21c87e1d2ddae39ec2aa5d7f0312e8d6b67e Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Tue, 31 Oct 2023 14:47:24 -0700 Subject: [PATCH 54/76] cleanup test --- pkg/kong/provisioning_test.go | 125 +++++++++++++++------------------- 1 file changed, 56 insertions(+), 69 deletions(-) diff --git a/pkg/kong/provisioning_test.go b/pkg/kong/provisioning_test.go index b71e955..6a9a1fe 100644 --- a/pkg/kong/provisioning_test.go +++ b/pkg/kong/provisioning_test.go @@ -3,6 +3,7 @@ package kong import ( "context" "encoding/json" + "fmt" "net/http" "net/http/httptest" "testing" @@ -13,25 +14,27 @@ import ( config "github.com/Axway/agents-kong/pkg/config/discovery" ) +func formatRequestKey(method, path string) string { + return fmt.Sprintf("%s-%s", method, path) +} + type response struct { code int dataIface interface{} data []byte } -func createClient(responses map[string]map[string]response) KongAPIClient { +func createClient(responses map[string]response) KongAPIClient { s := httptest.NewServer(http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { - if pathRes, foundPath := responses[req.URL.Path]; foundPath { - if res, found := pathRes[req.Method]; found { - resp.WriteHeader(res.code) - if res.dataIface != nil { - data, _ := json.Marshal(res.dataIface) - resp.Write(data) - } else { - resp.Write(res.data) - } - return + if res, found := responses[formatRequestKey(req.Method, req.URL.Path)]; found { + resp.WriteHeader(res.code) + if res.dataIface != nil { + data, _ := json.Marshal(res.dataIface) + resp.Write(data) + } else { + resp.Write(res.data) } + return } })) cfg := &config.KongGatewayConfig{ @@ -46,20 +49,18 @@ func TestCreateConsumer(t *testing.T) { expectErr bool id string name string - responses map[string]map[string]response + responses map[string]response }{ "find existing consumer": { expectErr: false, id: "existingID", name: "existingName", - responses: map[string]map[string]response{ - "/consumers/" + "existingID": { - http.MethodGet: { - code: http.StatusOK, - dataIface: &klib.Consumer{ - ID: klib.String("existingID"), - Username: klib.String("existingName"), - }, + responses: map[string]response{ + formatRequestKey(http.MethodGet, "/consumers/existingID"): { + code: http.StatusOK, + dataIface: &klib.Consumer{ + ID: klib.String("existingID"), + Username: klib.String("existingName"), }, }, }, @@ -68,19 +69,15 @@ func TestCreateConsumer(t *testing.T) { expectErr: false, id: "nameID", name: "newName", - responses: map[string]map[string]response{ - "/consumers/" + "nameID": { - http.MethodGet: { - code: http.StatusNotFound, - }, + responses: map[string]response{ + formatRequestKey(http.MethodGet, "/consumers/nameID"): { + code: http.StatusNotFound, }, - "/consumers": { - http.MethodPost: { - code: http.StatusCreated, - dataIface: &klib.Consumer{ - ID: klib.String("nameID"), - Username: klib.String("newName"), - }, + formatRequestKey(http.MethodPost, "/consumers"): { + code: http.StatusCreated, + dataIface: &klib.Consumer{ + ID: klib.String("nameID"), + Username: klib.String("newName"), }, }, }, @@ -89,16 +86,12 @@ func TestCreateConsumer(t *testing.T) { expectErr: true, id: "nameID", name: "newName", - responses: map[string]map[string]response{ - "/consumers/" + "nameID": { - http.MethodGet: { - code: http.StatusNotFound, - }, + responses: map[string]response{ + formatRequestKey(http.MethodGet, "/consumers/nameID"): { + code: http.StatusNotFound, }, - "/consumers": { - http.MethodPost: { - code: http.StatusBadRequest, - }, + formatRequestKey(http.MethodPost, "/consumers"): { + code: http.StatusBadRequest, }, }, }, @@ -121,50 +114,44 @@ func TestCreateConsumer(t *testing.T) { func TestDeleteConsumer(t *testing.T) { testCases := map[string]struct { expectErr bool - responses map[string]map[string]response + responses map[string]response }{ "consumer does not exist": { expectErr: false, - responses: map[string]map[string]response{ - "/consumers/" + "id": { - http.MethodGet: { - code: http.StatusNotFound, - }, + responses: map[string]response{ + formatRequestKey(http.MethodGet, "/consumers/id"): { + code: http.StatusNotFound, }, }, }, "delete consumer": { expectErr: false, - responses: map[string]map[string]response{ - "/consumers/" + "id": { - http.MethodGet: { - code: http.StatusOK, - dataIface: &klib.Consumer{ - ID: klib.String("id"), - Username: klib.String("name"), - }, - }, - http.MethodDelete: { - code: http.StatusAccepted, + responses: map[string]response{ + formatRequestKey(http.MethodGet, "/consumers/id"): { + code: http.StatusOK, + dataIface: &klib.Consumer{ + ID: klib.String("id"), + Username: klib.String("name"), }, }, + formatRequestKey(http.MethodDelete, "/consumers/id"): { + code: http.StatusAccepted, + }, }, }, "delete consumer error": { expectErr: true, - responses: map[string]map[string]response{ - "/consumers/" + "id": { - http.MethodGet: { - code: http.StatusOK, - dataIface: &klib.Consumer{ - ID: klib.String("id"), - Username: klib.String("name"), - }, - }, - http.MethodDelete: { - code: http.StatusBadRequest, + responses: map[string]response{ + formatRequestKey(http.MethodGet, "/consumers/id"): { + code: http.StatusOK, + dataIface: &klib.Consumer{ + ID: klib.String("id"), + Username: klib.String("name"), }, }, + formatRequestKey(http.MethodDelete, "/consumers/id"): { + code: http.StatusBadRequest, + }, }, }, } From c62b8d91741fa8a9b3c12ac0dac8d6734476d016 Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Tue, 31 Oct 2023 15:26:54 -0700 Subject: [PATCH 55/76] change to klib --- pkg/subscription/provision.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/subscription/provision.go b/pkg/subscription/provision.go index 6d099d3..dbabe69 100644 --- a/pkg/subscription/provision.go +++ b/pkg/subscription/provision.go @@ -5,7 +5,7 @@ import ( "errors" "fmt" - kongSDK "github.com/kong/go-kong/kong" + klib "github.com/kong/go-kong/kong" "github.com/sirupsen/logrus" "github.com/Axway/agent-sdk/pkg/agent" @@ -17,9 +17,9 @@ import ( "github.com/Axway/agents-kong/pkg/kong" ) -var constructors []func(*kongSDK.Client) Handler +var constructors []func(*klib.Client) Handler -func Add(constructor func(*kongSDK.Client) Handler) { +func Add(constructor func(*klib.Client) Handler) { constructors = append(constructors, constructor) } @@ -34,7 +34,7 @@ type Handler interface { type provisioner struct { logger log.FieldLogger client kong.KongAPIClient - kc *kongSDK.Client + kc *klib.Client handlers map[string]Handler } @@ -105,7 +105,7 @@ func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) } group := common.AclGroup consumerTags := []*string{&agentTag} - _, err = p.kc.ACLs.Create(ctx, &kongApplicationId, &kongSDK.ACLGroup{Group: &group, Tags: consumerTags}) + _, err = p.kc.ACLs.Create(ctx, &kongApplicationId, &klib.ACLGroup{Group: &group, Tags: consumerTags}) if err != nil { return Failed(rs, fmt.Errorf("failed to add acl group on consumer: %w", err)), nil } @@ -117,7 +117,7 @@ func (p provisioner) AccessRequestProvision(request provisioning.AccessRequest) planDesc := amplifyQuota.GetPlanName() quotaLimit := int(amplifyQuota.GetLimit()) p.logger.Info(" Plan name :%s, Plan Description :%s Quota Limit: %s", planName, planDesc, quotaLimit) - config := kongSDK.Configuration{ + config := klib.Configuration{ "limit": []interface{}{quotaLimit}, "policy": "local", } @@ -217,9 +217,9 @@ func GetProvisionKeyPropertyBuilder() provisioning.PropertyBuilder { IsString() } -//func addRateLimit(kc *kongSDK.Client, ctx context.Context, config map[string]interface{}, serviceId string) error { +//func addRateLimit(kc *klib.Client, ctx context.Context, config map[string]interface{}, serviceId string) error { // pluginName := "rate-limiting" -// rateLimitPlugin := kongSDK.Plugin{ +// rateLimitPlugin := klib.Plugin{ // Name: &pluginName, // Config: config, // } From 1c4745bbc22482e846ab37661e968a6cca52c80b Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Wed, 1 Nov 2023 15:16:27 +0200 Subject: [PATCH 56/76] update discovery process --- go.mod | 37 +++---- go.sum | 75 +++++++------- pkg/cmd/discovery/discoveryCmd.go | 3 +- pkg/config/discovery/config.go | 15 +-- pkg/gateway/client.go | 78 ++++++-------- pkg/gateway/definitions.go | 5 + pkg/kong/kongclient.go | 107 ++++++++++---------- pkg/kong/specmanager/devportal/devportal.go | 28 ----- pkg/kong/specmanager/localdir/localdir.go | 72 ------------- pkg/kong/specmanager/specmanager.go | 42 -------- pkg/processor/eventmapper.go | 5 +- 11 files changed, 165 insertions(+), 302 deletions(-) delete mode 100644 pkg/kong/specmanager/devportal/devportal.go delete mode 100644 pkg/kong/specmanager/localdir/localdir.go delete mode 100644 pkg/kong/specmanager/specmanager.go diff --git a/go.mod b/go.mod index 5e8629e..43b5e17 100644 --- a/go.mod +++ b/go.mod @@ -1,19 +1,19 @@ module github.com/Axway/agents-kong go 1.18 + //replace ( // github.com/Axway/agent-sdk => target latest +replace github.com/Axway/agent-sdk => /Users/acrosca/Work/Agents/agent-sdk -replace github.com/Axway/agent-sdk => /Users/rnatarajan/GolandProjects/agent-sdk require ( github.com/Axway/agent-sdk v1.1.58 github.com/elastic/beats/v7 v7.17.5 - github.com/google/uuid v1.3.0 - github.com/kong/go-kong v0.46.0 + github.com/google/uuid v1.3.1 + github.com/kong/go-kong v0.47.0 github.com/sirupsen/logrus v1.9.3 - github.com/tidwall/gjson v1.14.4 - gotest.tools v2.2.0+incompatible + github.com/tidwall/gjson v1.16.0 ) require ( @@ -53,7 +53,7 @@ require ( github.com/gabriel-vasile/mimetype v1.4.0 // indirect github.com/getkin/kin-openapi v0.76.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.2.4 // indirect github.com/go-ole/go-ole v1.2.5-0.20190920104607-14974a1cf647 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/swag v0.22.3 // indirect @@ -68,7 +68,7 @@ require ( github.com/gomodule/redigo v1.8.3 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-querystring v1.1.0 // indirect - github.com/google/gofuzz v1.1.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect github.com/googleapis/gnostic v0.4.1 // indirect github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect @@ -92,11 +92,11 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/kong/semver/v4 v4.0.1 // indirect - github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect github.com/lestrrat-go/blackmagic v1.0.1 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect + github.com/lestrrat-go/httprc v1.0.4 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect - github.com/lestrrat-go/jwx v1.2.26 // indirect + github.com/lestrrat-go/jwx/v2 v2.0.12 // indirect github.com/lestrrat-go/option v1.0.1 // indirect github.com/magefile/mage v1.13.0 // indirect github.com/magiconair/properties v1.8.6 // indirect @@ -117,6 +117,7 @@ require ( github.com/prometheus/procfs v0.7.3 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect + github.com/segmentio/asm v1.2.0 // indirect github.com/shirou/gopsutil v3.20.12+incompatible // indirect github.com/snowzach/rotatefilehook v0.0.0-20220211133110-53752135082d // indirect github.com/spf13/afero v1.8.2 // indirect @@ -142,20 +143,20 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect go.uber.org/zap v1.21.0 // indirect - golang.org/x/crypto v0.9.0 // indirect + golang.org/x/crypto v0.14.0 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect - golang.org/x/mod v0.9.0 // indirect - golang.org/x/net v0.10.0 // indirect + golang.org/x/mod v0.10.0 // indirect + golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/term v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect - golang.org/x/tools v0.7.0 // indirect + golang.org/x/tools v0.8.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220714211235-042d03aeabc9 // indirect google.golang.org/grpc v1.48.0 // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/jcmturner/aescts.v1 v1.0.1 // indirect @@ -170,7 +171,7 @@ require ( k8s.io/api v0.21.1 // indirect k8s.io/apimachinery v0.22.7 // indirect k8s.io/client-go v0.21.1 // indirect - k8s.io/klog/v2 v2.90.1 // indirect + k8s.io/klog/v2 v2.100.1 // indirect k8s.io/utils v0.0.0-20201110183641-67b214c5f920 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect diff --git a/go.sum b/go.sum index 922f1e0..8021d6b 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,6 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Axway/agent-sdk v1.1.58 h1:wnrnuRKus/aZPLhOPZr8FiCPbCQ4VJBra/Gp7iVFdbs= -github.com/Axway/agent-sdk v1.1.58/go.mod h1:xe6dIpQxE0LcSR+ssGKL4mfyLFbrLohdrB9iMYFUCdU= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= @@ -180,8 +178,8 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-ole/go-ole v1.2.5-0.20190920104607-14974a1cf647 h1:whypLownH338a3Ork2w9t0KUKtVxbXYySuz7V1YGsJo= github.com/go-ole/go-ole v1.2.5-0.20190920104607-14974a1cf647/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= @@ -247,7 +245,7 @@ github.com/gomodule/redigo v1.8.3 h1:HR0kYDX2RJZvAup8CsiJwxB4dTCSC0AaUq6S4SiLwUc github.com/gomodule/redigo v1.8.3/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= 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/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= 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= @@ -264,8 +262,9 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -282,8 +281,8 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLe github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 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.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= @@ -356,8 +355,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/kong/go-kong v0.46.0 h1:9I6nlX63WymU5Sg+d13iZDVwpW5vXh8/v0zarU27dzI= -github.com/kong/go-kong v0.46.0/go.mod h1:41Sot1N/n8UHBp+gE/6nOw3vuzoHbhMSyU/zOS7VzPE= +github.com/kong/go-kong v0.47.0 h1:fuZjRnUChITogljM4mY4HGGTKTaZM50970Wwg6EvQgs= +github.com/kong/go-kong v0.47.0/go.mod h1:QaLx1EsT+roe5V6h7aKghwLn0bXg7l/Bg8wzlcCmygc= github.com/kong/semver/v4 v4.0.1 h1:DIcNR8W3gfx0KabFBADPalxxsp+q/5COwIFkkhrFQ2Y= github.com/kong/semver/v4 v4.0.1/go.mod h1:LImQ0oT15pJvSns/hs2laLca2zcYoHu5EsSNY0J6/QA= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -372,16 +371,16 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= -github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80= github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= +github.com/lestrrat-go/httprc v1.0.4 h1:bAZymwoZQb+Oq8MEbyipag7iSq6YIga8Wj6GOiJGdI8= +github.com/lestrrat-go/httprc v1.0.4/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo= github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx v1.2.26 h1:4iFo8FPRZGDYe1t19mQP0zTRqA7n8HnJ5lkIiDvJcB0= -github.com/lestrrat-go/jwx v1.2.26/go.mod h1:MaiCdGbn3/cckbOFSCluJlJMmp9dmZm5hDuIkx8ftpQ= +github.com/lestrrat-go/jwx/v2 v2.0.12 h1:3d589+5w/b9b7S3DneICPW16AqTyYXB7VRjgluSDWeA= +github.com/lestrrat-go/jwx/v2 v2.0.12/go.mod h1:Mq4KN1mM7bp+5z/W5HS8aCNs5RKZ911G/0y2qUjAQuQ= github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= @@ -452,10 +451,12 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5X github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis= github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4= +github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= +github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/shirou/gopsutil v3.20.12+incompatible h1:6VEGkOXP/eP4o2Ilk8cSsX0PhOEfX6leqAnD+urrp9M= github.com/shirou/gopsutil v3.20.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -498,8 +499,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs= github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= -github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= -github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg= +github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= @@ -574,8 +575,9 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= 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= @@ -615,8 +617,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= -golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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= @@ -660,8 +662,9 @@ golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= 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= @@ -749,15 +752,18 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= 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= @@ -767,8 +773,10 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 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= @@ -833,8 +841,8 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= 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= @@ -939,8 +947,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -980,7 +988,6 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/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= 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= @@ -1000,10 +1007,10 @@ k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs= 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.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= -k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= -k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= 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= diff --git a/pkg/cmd/discovery/discoveryCmd.go b/pkg/cmd/discovery/discoveryCmd.go index 5e97d66..b63eee7 100644 --- a/pkg/cmd/discovery/discoveryCmd.go +++ b/pkg/cmd/discovery/discoveryCmd.go @@ -48,7 +48,7 @@ func run() error { for { err = gatewayClient.DiscoverAPIs() if err != nil { - log.Error("error in processing: %s", err) + log.Errorf("error in processing: %v", err) stopChan <- struct{}{} } log.Infof("next poll in %s", agentConfig.CentralCfg.GetPollInterval()) @@ -79,6 +79,7 @@ func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { ProxyHttpsPort: rootProps.IntPropertyValue("kong.proxyEndpointProtocols.https"), SpecHomePath: rootProps.StringPropertyValue("kong.specHomePath"), SpecDevPortalEnabled: rootProps.BoolPropertyValue("kong.specDevPortalEnabled"), + SpecDownloadPaths: rootProps.StringSlicePropertyValue("kong.specDownloadPaths"), } agentConfig = config.AgentConfig{ diff --git a/pkg/config/discovery/config.go b/pkg/config/discovery/config.go index f6b112f..af19531 100644 --- a/pkg/config/discovery/config.go +++ b/pkg/config/discovery/config.go @@ -16,13 +16,14 @@ type AgentConfig struct { // KongGatewayConfig - represents the config for gateway type KongGatewayConfig struct { corecfg.IConfigValidator - AdminEndpoint string `config:"adminEndpoint"` - Token string `config:"token"` - ProxyEndpoint string `config:"proxyEndpoint"` - ProxyHttpPort int `config:"proxyHttpPort"` - ProxyHttpsPort int `config:"proxyHttpsPort"` - SpecHomePath string `config:"specHomePath"` - SpecDevPortalEnabled bool `config:"specDevPortalEnabled"` + AdminEndpoint string `config:"adminEndpoint"` + Token string `config:"token"` + ProxyEndpoint string `config:"proxyEndpoint"` + ProxyHttpPort int `config:"proxyHttpPort"` + ProxyHttpsPort int `config:"proxyHttpsPort"` + SpecHomePath string `config:"specHomePath"` + SpecDevPortalEnabled bool `config:"specDevPortalEnabled"` + SpecDownloadPaths []string `config:"specDownloadPaths"` } // ValidateCfg - Validates the gateway config diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 7802364..ea9d7d0 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -4,16 +4,13 @@ import ( "context" "crypto/sha256" "fmt" + "net/http" + "sync" + "github.com/Axway/agent-sdk/pkg/apic/provisioning" "github.com/Axway/agents-kong/pkg/common" "github.com/Axway/agents-kong/pkg/subscription" "github.com/sirupsen/logrus" - "net/http" - "sync" - - "github.com/Axway/agents-kong/pkg/kong/specmanager" - "github.com/Axway/agents-kong/pkg/kong/specmanager/devportal" - "github.com/Axway/agents-kong/pkg/kong/specmanager/localdir" "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/apic" @@ -38,15 +35,10 @@ func NewClient(agentConfig config.AgentConfig) (*Client, error) { return nil, err } apicClient := NewCentralClient(agent.GetCentralClient(), agentConfig.CentralCfg) - if agentConfig.KongGatewayCfg.SpecDevPortalEnabled { - specmanager.AddSource(devportal.NewSpecificationSource(kongClient)) - } - if len(agentConfig.KongGatewayCfg.SpecHomePath) > 0 { - specmanager.AddSource(localdir.NewSpecificationSource(agentConfig.KongGatewayCfg.SpecHomePath)) - } daCache := cache.New() logger := logrus.WithFields(logrus.Fields{ "component": "agent", + "package": "discovery", }) plugins, err := kongClient.Plugins.ListAll(context.Background()) @@ -66,6 +58,8 @@ func NewClient(agentConfig config.AgentConfig) (*Client, error) { } subscription.NewProvisioner(kongClient.Client, logger) return &Client{ + ctx: context.Background(), + logger: logger, centralCfg: agentConfig.CentralCfg, kongGatewayCfg: kongGatewayConfig, kongClient: kongClient, @@ -86,13 +80,16 @@ func findACLGroup(groups []interface{}) string { } func (gc *Client) DiscoverAPIs() error { + gc.logger.Info("execute discovery process") + plugins := kutil.Plugins{PluginLister: gc.kongClient.GetKongPlugins()} gc.plugins = plugins - services, err := gc.kongClient.ListServices(context.Background()) + services, err := gc.kongClient.ListServices(gc.ctx) if err != nil { - log.Errorf("failed to get services: %s", err) + gc.logger.WithError(err).Error("failed to get services") return err } + gc.processKongServicesList(services) return nil } @@ -103,7 +100,7 @@ func (gc *Client) processKongServicesList(services []*klib.Service) { wg.Add(1) go func(service *klib.Service, wg *sync.WaitGroup) { defer wg.Done() - err := gc.processSingleKongService(context.Background(), service) + err := gc.processSingleKongService(gc.ctx, service) if err != nil { log.Error(err) } @@ -113,12 +110,15 @@ func (gc *Client) processKongServicesList(services []*klib.Service) { } func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Service) error { + gc.logger.Infof("processing service %s", *service.Name) + proxyEndpoint := gc.kongGatewayCfg.ProxyEndpoint httpPort := gc.kongGatewayCfg.ProxyHttpPort httpsPort := gc.kongGatewayCfg.ProxyHttpsPort routes, err := gc.kongClient.ListRoutesForService(ctx, *service.ID) if err != nil { + gc.logger.WithError(err).Errorf("failed to get routes for service %s", *service.Name) return err } if len(routes) == 0 { @@ -130,32 +130,35 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se apiPlugins, err := gc.plugins.GetEffectivePlugins(*route.ID, *service.ID) if err != nil { - return fmt.Errorf("failed to get plugins for route %s: %w", *route.ID, err) + gc.logger.WithError(err).Errorf("failed to get plugins for route %s", *route.ID) + return err } - kongServiceSpec, err := specmanager.GetSpecification(ctx, service) + kongServiceSpec, err := gc.kongClient.GetSpecForService(ctx, *service.ID) if err != nil { - return fmt.Errorf("failed to get spec for %s: %s", *service.Name, err) + gc.logger.WithError(err).Errorf("failed to get spec for service %s", *service.Name) + return err } oasSpec := Openapi{ - spec: kongServiceSpec.Contents, + spec: string(kongServiceSpec), } endpoints := gc.processKongRoute(proxyEndpoint, oasSpec.BasePath(), route, httpPort, httpsPort) serviceBody, err := gc.processKongAPI(*route.ID, service, oasSpec, endpoints, apiPlugins) - if err != nil { return err } if serviceBody == nil { - log.Debugf("not processing '%s' since no changes were detected", *service.Name) + gc.logger.Debugf("not processing '%s' since no changes were detected", *service.Name) return nil } err = agent.PublishAPI(*serviceBody) if err != nil { - return fmt.Errorf("failed to publish api: %s", err) + gc.logger.WithError(err).Error("failed to publish api") + return err } - log.Infof("Published API '%s' to central", serviceBody.APIName) + + gc.logger.Infof("Published API '%s' to central", serviceBody.APIName) return nil } @@ -205,15 +208,14 @@ func (gc *Client) processKongAPI( isAlreadyPublished, checksum := isPublished(&kongAPI, gc.cache) // If true, then the api is published and there were no changes detected if isAlreadyPublished { - logrus.Debug("api is already published") + gc.logger.Debug("api is already published") return nil, nil } err := gc.cache.Set(checksum, kongAPI) if err != nil { - logrus.Errorf("failed to save api to cache: %s", err) + gc.logger.WithError(err).Error("failed to save api to cache") } - //specType, _ := getSpecType(kongAPI.swaggerSpec) - //logrus.Infof("Specification Type %s", specType) + ardName, crdName := getFirstAuthPluginArdAndCrd(apiPlugins) logrus.Infof("API %v Access Request Definition %s Credential Request Definition %s", kongAPI.name, ardName, crdName) kongAPI.accessRequestDefinition = ardName @@ -226,7 +228,8 @@ func (gc *Client) processKongAPI( kongAPI.agentDetails = agentDetails serviceBody, err := kongAPI.buildServiceBody() if err != nil { - return nil, fmt.Errorf("failed to build service body: %v", serviceBody) + gc.logger.WithError(err).Error("failed to build service body") + return nil, err } return &serviceBody, nil } @@ -251,7 +254,6 @@ func newKongAPI( } func (ka *KongAPI) buildServiceBody() (apic.ServiceBody, error) { - tags := map[string]interface{}{} if ka.tags != nil { for _, tag := range ka.tags { @@ -287,24 +289,6 @@ func (ka *KongAPI) buildServiceBody() (apic.ServiceBody, error) { SetCredentialRequestDefinitions(ka.CRDs).Build() } -//func getSpecType(specContent []byte) (string, error) { -// -// if specContent != nil { -// jsonMap := make(map[string]interface{}) -// err := json.Unmarshal(specContent, &jsonMap) -// if err != nil { -// logrus.Info("Not an swagger or openapi spec") -// return "", nil -// } -// if _, isSwagger := jsonMap["swagger"]; isSwagger { -// return apic.Oas2, nil -// } else if _, isOpenAPI := jsonMap["openapi"]; isOpenAPI { -// return apic.Oas3, nil -// } -// } -// return "", nil -//} - // makeChecksum generates a makeChecksum for the api for change detection func makeChecksum(val interface{}) string { sum := sha256.Sum256([]byte(fmt.Sprintf("%v", val))) diff --git a/pkg/gateway/definitions.go b/pkg/gateway/definitions.go index 4434086..e0e879f 100644 --- a/pkg/gateway/definitions.go +++ b/pkg/gateway/definitions.go @@ -1,16 +1,21 @@ package gateway import ( + "context" + "github.com/Axway/agent-sdk/pkg/apic" "github.com/Axway/agent-sdk/pkg/cache" corecfg "github.com/Axway/agent-sdk/pkg/config" "github.com/Axway/agents-kong/pkg/kong" + "github.com/sirupsen/logrus" config "github.com/Axway/agents-kong/pkg/config/discovery" kutil "github.com/Axway/agents-kong/pkg/kong" ) type Client struct { + ctx context.Context + logger logrus.FieldLogger centralCfg corecfg.CentralConfig kongGatewayCfg *config.KongGatewayConfig kongClient kong.KongAPIClient diff --git a/pkg/kong/kongclient.go b/pkg/kong/kongclient.go index fa44d4e..2b87fb0 100644 --- a/pkg/kong/kongclient.go +++ b/pkg/kong/kongclient.go @@ -2,14 +2,14 @@ package kong import ( "context" - "encoding/json" "fmt" "io" "net/http" + "time" - "github.com/Axway/agents-kong/pkg/kong/specmanager" - + "github.com/Axway/agent-sdk/pkg/apic" config "github.com/Axway/agents-kong/pkg/config/discovery" + "github.com/sirupsen/logrus" klib "github.com/kong/go-kong/kong" ) @@ -17,14 +17,17 @@ import ( type KongAPIClient interface { ListServices(ctx context.Context) ([]*klib.Service, error) ListRoutesForService(ctx context.Context, serviceId string) ([]*klib.Route, error) - GetSpecForService(ctx context.Context, serviceId string) (*specmanager.KongServiceSpec, error) + GetSpecForService(ctx context.Context, backendURL string) ([]byte, error) GetKongPlugins() *Plugins } type KongClient struct { *klib.Client + logger logrus.FieldLogger baseClient DoRequest kongAdminEndpoint string + specPaths []string + clientTimeout time.Duration } func NewKongClient(baseClient *http.Client, kongConfig *config.KongGatewayConfig) (*KongClient, error) { @@ -38,14 +41,23 @@ func NewKongClient(baseClient *http.Client, kongConfig *config.KongGatewayConfig baseClient = client } + logger := logrus.WithFields(logrus.Fields{ + "component": "agent", + "package": "discovery", + }) + baseKongClient, err := klib.NewClient(&kongConfig.AdminEndpoint, baseClient) if err != nil { + logger.WithError(err).Error("failed to create kong client") return nil, err } return &KongClient{ + logger: logger, Client: baseKongClient, baseClient: baseClient, kongAdminEndpoint: kongConfig.AdminEndpoint, + specPaths: kongConfig.SpecDownloadPaths, + clientTimeout: 10 * time.Second, }, nil } @@ -58,57 +70,50 @@ func (k KongClient) ListRoutesForService(ctx context.Context, serviceId string) return routes, err } -func (k KongClient) GetSpecForService(ctx context.Context, serviceId string) (*specmanager.KongServiceSpec, error) { - endpoint := fmt.Sprintf("%s/services/%s/document_objects", k.kongAdminEndpoint, serviceId) - req, err := http.NewRequestWithContext(ctx, "GET", endpoint, nil) - if err != nil { - return nil, fmt.Errorf("failed to create request: %s", err) +func (k KongClient) GetSpecForService(ctx context.Context, backendURL string) ([]byte, error) { + if len(k.specPaths) == 0 { + k.logger.Info("no spec paths configured") + return nil, nil } - res, err := k.baseClient.Do(req) - if err != nil { - return nil, fmt.Errorf("failed to execute request: %s", err) - } - data, err := io.ReadAll(res.Body) - if err != nil { - return nil, fmt.Errorf("failed to read body: %s", err) - } - documents := &DocumentObjects{} - err = json.Unmarshal(data, documents) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal: %s", err) - } - if len(documents.Data) < 1 { - return nil, fmt.Errorf("no documents found") - } - return k.getSpec(ctx, documents.Data[0].Path) -} -func (k KongClient) getSpec(ctx context.Context, path string) (*specmanager.KongServiceSpec, error) { - endpoint := fmt.Sprintf("%s/default/files/%s", k.kongAdminEndpoint, path) - req, err := http.NewRequestWithContext(ctx, "GET", endpoint, nil) - if err != nil { - return nil, fmt.Errorf("failed to create request: %s", err) - } - - res, err := k.baseClient.Do(req) - if err != nil { - return nil, fmt.Errorf("failed to execute request: %s", err) - } - - data, err := io.ReadAll(res.Body) - if err != nil { - return nil, fmt.Errorf("failed to read body: %s", err) + ctxTimeout, cancel := context.WithTimeout(ctx, k.clientTimeout) + defer cancel() + + var specContent []byte + + for _, specPath := range k.specPaths { + endpoint := fmt.Sprintf("%s/%s", backendURL, specPath) + req, err := http.NewRequestWithContext(ctxTimeout, "GET", endpoint, nil) + if err != nil { + k.logger.WithError(err).Error("failed to create request") + return nil, err + } + res, err := k.baseClient.Do(req) + if err != nil { + k.logger.WithError(err).Error("failed to execute request") + return nil, err + } + if res.StatusCode != http.StatusOK { + continue + } + + specContent, err = io.ReadAll(res.Body) + if err != nil { + k.logger.WithError(err).Error("failed to read body") + return nil, err + } + + specParser := apic.NewSpecResourceParser(specContent, "") + err = specParser.Parse() + if err != nil { + k.logger.Debug("invalid api spec") + continue + } + // break if spec is validated + break } - kongServiceSpec := &specmanager.KongServiceSpec{} - err = json.Unmarshal(data, kongServiceSpec) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal: %s", err) - } - if len(kongServiceSpec.Contents) == 0 { - return nil, fmt.Errorf("spec not found at '%s'", path) - } - return kongServiceSpec, nil + return specContent, nil } func (k KongClient) GetKongPlugins() *Plugins { diff --git a/pkg/kong/specmanager/devportal/devportal.go b/pkg/kong/specmanager/devportal/devportal.go deleted file mode 100644 index ca40cf0..0000000 --- a/pkg/kong/specmanager/devportal/devportal.go +++ /dev/null @@ -1,28 +0,0 @@ -package devportal - -import ( - "context" - kutil "github.com/Axway/agents-kong/pkg/kong" - "github.com/Axway/agents-kong/pkg/kong/specmanager" - klib "github.com/kong/go-kong/kong" -) - -type sourceConfig struct { - name string - kongClient kutil.KongAPIClient -} - -func NewSpecificationSource(kongClient kutil.KongAPIClient) specmanager.SpecificationSource { - return sourceConfig{ - name: "dev-portal", - kongClient: kongClient, - } -} - -func (sc sourceConfig) Name() *string { - return &sc.name -} - -func (sc sourceConfig) GetSpecForService(ctx context.Context, service *klib.Service) (*specmanager.KongServiceSpec, error) { - return sc.kongClient.GetSpecForService(ctx, *service.ID) -} diff --git a/pkg/kong/specmanager/localdir/localdir.go b/pkg/kong/specmanager/localdir/localdir.go deleted file mode 100644 index 0f620d7..0000000 --- a/pkg/kong/specmanager/localdir/localdir.go +++ /dev/null @@ -1,72 +0,0 @@ -package localdir - -import ( - "context" - "fmt" - "os" - "path" - "strings" - - "github.com/Axway/agent-sdk/pkg/util/log" - "github.com/Axway/agents-kong/pkg/kong/specmanager" - klib "github.com/kong/go-kong/kong" -) - -const tagPrefix = "spec_local_" - -type sourceConfig struct { - name string - rootPath string -} - -func NewSpecificationSource(rootPath string) specmanager.SpecificationSource { - return sourceConfig{ - name: "local", - rootPath: rootPath, - } -} - -func (sc sourceConfig) Name() *string { - return &sc.name -} - -func (sc sourceConfig) GetSpecForService(ctx context.Context, service *klib.Service) (*specmanager.KongServiceSpec, error) { - specTag := "" - for _, tag := range service.Tags { - if strings.HasPrefix(*tag, tagPrefix) { - specTag = *tag - } - } - - if len(specTag) > 0 { - name := specTag[len(tagPrefix):] - - return sc.loadSpecFile(name) - } - log.Infof("no specification tag found for service %s (%s)", *service.Name, *service.ID) - return nil, nil -} - -func (sc sourceConfig) loadSpecFile(name string) (*specmanager.KongServiceSpec, error) { - specFilePath := path.Join(sc.rootPath, name) - - if _, err := os.Stat(specFilePath); os.IsNotExist(err) { - log.Warnf("specification file not found %s", specFilePath) - return nil, nil - } - - data, err := os.ReadFile(specFilePath) - if err != nil { - return nil, fmt.Errorf("error on reading spec file %s: %s", specFilePath, err) - } - - kongServiceSpec := &specmanager.KongServiceSpec{ - Contents: string(data), - CreatedAt: 0, - ID: "", - Path: specFilePath, - Checksum: "", - } - - return kongServiceSpec, nil -} diff --git a/pkg/kong/specmanager/specmanager.go b/pkg/kong/specmanager/specmanager.go deleted file mode 100644 index c4aeff0..0000000 --- a/pkg/kong/specmanager/specmanager.go +++ /dev/null @@ -1,42 +0,0 @@ -package specmanager - -import ( - "context" - "fmt" - "github.com/Axway/agent-sdk/pkg/util/log" - "github.com/kong/go-kong/kong" -) - -type KongServiceSpec struct { - Contents string `json:"contents"` - CreatedAt int `json:"created_at"` - ID string `json:"id"` - Path string `json:"path"` - Checksum string `json:"checksum"` -} - -type SpecificationSource interface { - Name() *string - GetSpecForService(ctx context.Context, service *kong.Service) (*KongServiceSpec, error) -} - -var specificationManager struct { - sources []SpecificationSource -} - -func AddSource(source SpecificationSource) { - specificationManager.sources = append(specificationManager.sources, source) - log.Infof("specification source added: %s", *source.Name()) -} - -func GetSpecification(ctx context.Context, service *kong.Service) (*KongServiceSpec, error) { - for _, source := range specificationManager.sources { - spec, err := source.GetSpecForService(ctx, service) - if err == nil { - if spec != nil { - return spec, nil - } - } - } - return nil, fmt.Errorf("no specification found for service %s (%s)", *service.Name, *service.ID) -} diff --git a/pkg/processor/eventmapper.go b/pkg/processor/eventmapper.go index 3cda66d..be3ec21 100644 --- a/pkg/processor/eventmapper.go +++ b/pkg/processor/eventmapper.go @@ -11,6 +11,7 @@ import ( "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/transaction" + "github.com/Axway/agent-sdk/pkg/transaction/util" "github.com/Axway/agent-sdk/pkg/util/log" ) @@ -157,12 +158,12 @@ func (m *EventMapper) createSummaryEvent(ktle KongTrafficLogEntry, teamID string ktle.Request.URI, ktle.Request.URL). SetDuration(ktle.Latencies.Request). - SetProxy(transaction.FormatProxyID(ktle.Route.ID), + SetProxy(util.FormatProxyID(ktle.Route.ID), ktle.Service.Name, 1) if ktle.Consumer != nil { - builder.SetApplication(transaction.FormatApplicationID(ktle.Consumer.ID), ktle.Consumer.Username) + builder.SetApplication(util.FormatApplicationID(ktle.Consumer.ID), ktle.Consumer.Username) } return builder.Build() From 4723404386de6e0cf62d7627298db3e5870b7f5a Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Wed, 1 Nov 2023 15:46:57 +0200 Subject: [PATCH 57/76] AOIGOV-26571 small fixes --- go.mod | 7 +++---- go.sum | 17 +++++++---------- pkg/gateway/client.go | 2 +- pkg/gateway/definitions.go | 7 +++---- 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 43b5e17..259a9fd 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 //replace ( // github.com/Axway/agent-sdk => target latest -replace github.com/Axway/agent-sdk => /Users/acrosca/Work/Agents/agent-sdk +// replace github.com/Axway/agent-sdk => /Users/acrosca/Work/Agents/agent-sdk require ( github.com/Axway/agent-sdk v1.1.58 @@ -92,11 +92,11 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/kong/semver/v4 v4.0.1 // indirect + github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect github.com/lestrrat-go/blackmagic v1.0.1 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect - github.com/lestrrat-go/httprc v1.0.4 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect - github.com/lestrrat-go/jwx/v2 v2.0.12 // indirect + github.com/lestrrat-go/jwx v1.2.26 // indirect github.com/lestrrat-go/option v1.0.1 // indirect github.com/magefile/mage v1.13.0 // indirect github.com/magiconair/properties v1.8.6 // indirect @@ -117,7 +117,6 @@ require ( github.com/prometheus/procfs v0.7.3 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect - github.com/segmentio/asm v1.2.0 // indirect github.com/shirou/gopsutil v3.20.12+incompatible // indirect github.com/snowzach/rotatefilehook v0.0.0-20220211133110-53752135082d // indirect github.com/spf13/afero v1.8.2 // indirect diff --git a/go.sum b/go.sum index 8021d6b..855ba37 100644 --- a/go.sum +++ b/go.sum @@ -36,6 +36,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Axway/agent-sdk v1.1.58 h1:wnrnuRKus/aZPLhOPZr8FiCPbCQ4VJBra/Gp7iVFdbs= +github.com/Axway/agent-sdk v1.1.58/go.mod h1:xe6dIpQxE0LcSR+ssGKL4mfyLFbrLohdrB9iMYFUCdU= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= @@ -371,16 +373,16 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= +github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80= github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/httprc v1.0.4 h1:bAZymwoZQb+Oq8MEbyipag7iSq6YIga8Wj6GOiJGdI8= -github.com/lestrrat-go/httprc v1.0.4/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo= github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx/v2 v2.0.12 h1:3d589+5w/b9b7S3DneICPW16AqTyYXB7VRjgluSDWeA= -github.com/lestrrat-go/jwx/v2 v2.0.12/go.mod h1:Mq4KN1mM7bp+5z/W5HS8aCNs5RKZ911G/0y2qUjAQuQ= +github.com/lestrrat-go/jwx v1.2.26 h1:4iFo8FPRZGDYe1t19mQP0zTRqA7n8HnJ5lkIiDvJcB0= +github.com/lestrrat-go/jwx v1.2.26/go.mod h1:MaiCdGbn3/cckbOFSCluJlJMmp9dmZm5hDuIkx8ftpQ= github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= @@ -455,8 +457,6 @@ github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBO github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis= github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4= -github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= -github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/shirou/gopsutil v3.20.12+incompatible h1:6VEGkOXP/eP4o2Ilk8cSsX0PhOEfX6leqAnD+urrp9M= github.com/shirou/gopsutil v3.20.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -575,7 +575,7 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -752,7 +752,6 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -761,7 +760,6 @@ golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -774,7 +772,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index ea9d7d0..823e6ac 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -134,7 +134,7 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se return err } - kongServiceSpec, err := gc.kongClient.GetSpecForService(ctx, *service.ID) + kongServiceSpec, err := gc.kongClient.GetSpecForService(ctx, *service.Host) if err != nil { gc.logger.WithError(err).Errorf("failed to get spec for service %s", *service.Name) return err diff --git a/pkg/gateway/definitions.go b/pkg/gateway/definitions.go index e0e879f..19d04da 100644 --- a/pkg/gateway/definitions.go +++ b/pkg/gateway/definitions.go @@ -20,10 +20,9 @@ type Client struct { kongGatewayCfg *config.KongGatewayConfig kongClient kong.KongAPIClient apicClient CentralClient - //subscriptionManager *subscription.Manager - plugins kutil.Plugins - cache cache.Cache - mode string + plugins kutil.Plugins + cache cache.Cache + mode string } type KongAPI struct { From f338280ecfcc7e88462fae6fa8c3fa31c2c1a332 Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Wed, 1 Nov 2023 16:27:54 +0200 Subject: [PATCH 58/76] APIGOV-26571 remove unused fields --- pkg/cmd/discovery/discoveryCmd.go | 14 ++++++-------- pkg/config/discovery/config.go | 14 ++++++-------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/pkg/cmd/discovery/discoveryCmd.go b/pkg/cmd/discovery/discoveryCmd.go index b63eee7..9900469 100644 --- a/pkg/cmd/discovery/discoveryCmd.go +++ b/pkg/cmd/discovery/discoveryCmd.go @@ -72,14 +72,12 @@ func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { // Parse the config from bound properties and setup gateway config gatewayConfig := &config.KongGatewayConfig{ - AdminEndpoint: rootProps.StringPropertyValue("kong.adminEndpoint"), - Token: rootProps.StringPropertyValue("kong.token"), - ProxyEndpoint: rootProps.StringPropertyValue("kong.proxyEndpoint"), - ProxyHttpPort: rootProps.IntPropertyValue("kong.proxyEndpointProtocols.http"), - ProxyHttpsPort: rootProps.IntPropertyValue("kong.proxyEndpointProtocols.https"), - SpecHomePath: rootProps.StringPropertyValue("kong.specHomePath"), - SpecDevPortalEnabled: rootProps.BoolPropertyValue("kong.specDevPortalEnabled"), - SpecDownloadPaths: rootProps.StringSlicePropertyValue("kong.specDownloadPaths"), + AdminEndpoint: rootProps.StringPropertyValue("kong.adminEndpoint"), + Token: rootProps.StringPropertyValue("kong.token"), + ProxyEndpoint: rootProps.StringPropertyValue("kong.proxyEndpoint"), + ProxyHttpPort: rootProps.IntPropertyValue("kong.proxyEndpointProtocols.http"), + ProxyHttpsPort: rootProps.IntPropertyValue("kong.proxyEndpointProtocols.https"), + SpecDownloadPaths: rootProps.StringSlicePropertyValue("kong.specDownloadPaths"), } agentConfig = config.AgentConfig{ diff --git a/pkg/config/discovery/config.go b/pkg/config/discovery/config.go index af19531..713dde9 100644 --- a/pkg/config/discovery/config.go +++ b/pkg/config/discovery/config.go @@ -16,14 +16,12 @@ type AgentConfig struct { // KongGatewayConfig - represents the config for gateway type KongGatewayConfig struct { corecfg.IConfigValidator - AdminEndpoint string `config:"adminEndpoint"` - Token string `config:"token"` - ProxyEndpoint string `config:"proxyEndpoint"` - ProxyHttpPort int `config:"proxyHttpPort"` - ProxyHttpsPort int `config:"proxyHttpsPort"` - SpecHomePath string `config:"specHomePath"` - SpecDevPortalEnabled bool `config:"specDevPortalEnabled"` - SpecDownloadPaths []string `config:"specDownloadPaths"` + AdminEndpoint string `config:"adminEndpoint"` + Token string `config:"token"` + ProxyEndpoint string `config:"proxyEndpoint"` + ProxyHttpPort int `config:"proxyHttpPort"` + ProxyHttpsPort int `config:"proxyHttpsPort"` + SpecDownloadPaths []string `config:"specDownloadPaths"` } // ValidateCfg - Validates the gateway config From 74f0f3c8ab8d910467b739a7591e61911702c53d Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Wed, 1 Nov 2023 14:18:06 -0700 Subject: [PATCH 59/76] cleanup app provisioning --- pkg/subscription/application.go | 66 -------- pkg/subscription/application/application.go | 96 +++++++++++ .../application/application_test.go | 158 ++++++++++++++++++ pkg/subscription/provision.go | 9 + 4 files changed, 263 insertions(+), 66 deletions(-) delete mode 100644 pkg/subscription/application.go create mode 100644 pkg/subscription/application/application.go create mode 100644 pkg/subscription/application/application_test.go diff --git a/pkg/subscription/application.go b/pkg/subscription/application.go deleted file mode 100644 index 3aeb295..0000000 --- a/pkg/subscription/application.go +++ /dev/null @@ -1,66 +0,0 @@ -package subscription - -import ( - "context" - "errors" - - "github.com/Axway/agent-sdk/pkg/apic/provisioning" - "github.com/Axway/agents-kong/pkg/common" -) - -const ( - logFieldAppID = "appID" - logFieldAppName = "appName" -) - -func (p provisioner) ApplicationRequestProvision(request provisioning.ApplicationRequest) provisioning.RequestStatus { - log := p.logger - log.Info("provisioning application") - - ctx := context.Background() - rs := provisioning.NewRequestStatusBuilder() - - appName := request.GetManagedApplicationName() - if appName == "" { - log.Error("could not find the managed application name on the resource") - return Failed(rs, notFound("managed application name")) - } - appID := request.GetID() - log = log.WithField(logFieldAppID, appID).WithField(logFieldAppName, appName) - - consumer, err := p.client.CreateConsumer(ctx, appID, appName) - if err != nil { - log.WithError(err).Error("error creating kong consumer") - return Failed(rs, errors.New("could not create a new consumer in kong")) - } - - // process application create - rs.AddProperty(common.AttrAppID, *consumer.ID) - log.Info("created application") - - return rs.Success() -} - -func (p provisioner) ApplicationRequestDeprovision(request provisioning.ApplicationRequest) provisioning.RequestStatus { - log := p.logger - log.Info("deprovisioning application") - - ctx := context.Background() - rs := provisioning.NewRequestStatusBuilder() - - appID := request.GetApplicationDetailsValue(common.AttrAppID) - if appID == "" { - log.Error("could not find the consumer id on the managed application resource") - return Failed(rs, notFound(common.AttrAppID)) - } - log = log.WithField(logFieldAppID, appID).WithField(logFieldAppName, request.GetManagedApplicationName()) - - err := p.client.DeleteConsumer(ctx, appID) - if err != nil { - log.WithError(err).Error("error deleting kong consumer") - return Failed(rs, errors.New("could not remove consumer in kong")) - } - p.logger.Info("removed application") - - return rs.Success() -} diff --git a/pkg/subscription/application/application.go b/pkg/subscription/application/application.go new file mode 100644 index 0000000..f6ed781 --- /dev/null +++ b/pkg/subscription/application/application.go @@ -0,0 +1,96 @@ +package application + +import ( + "context" + "fmt" + + "github.com/Axway/agent-sdk/pkg/apic/provisioning" + "github.com/Axway/agent-sdk/pkg/util/log" + "github.com/Axway/agents-kong/pkg/common" + + klib "github.com/kong/go-kong/kong" +) + +const ( + logFieldAppID = "appID" + logFieldAppName = "appName" + logFieldConsumerID = "consumerID" +) + +type appClient interface { + CreateConsumer(ctx context.Context, id, name string) (*klib.Consumer, error) + DeleteConsumer(ctx context.Context, id string) error +} + +type AppProvisioner struct { + ctx context.Context + logger log.FieldLogger + client appClient + appName string + appID string + consumerID string +} + +func NewApplicationProvisioner(ctx context.Context, client appClient, request provisioning.ApplicationRequest) AppProvisioner { + a := AppProvisioner{ + ctx: context.Background(), + logger: log.NewFieldLogger(). + WithComponent("AppProvisioner"). + WithPackage("application"), + client: client, + appName: request.GetManagedApplicationName(), + appID: request.GetID(), + consumerID: request.GetApplicationDetailsValue(common.AttrAppID), + } + if a.appName != "" { + a.logger = a.logger.WithField(logFieldAppName, a.appName) + } + if a.appID != "" { + a.logger = a.logger.WithField(logFieldAppID, a.appID) + } + if a.consumerID != "" { + a.logger = a.logger.WithField(logFieldConsumerID, a.consumerID) + } + return a +} + +func (a AppProvisioner) Provision() provisioning.RequestStatus { + a.logger.Info("provisioning application") + + rs := provisioning.NewRequestStatusBuilder() + if a.appName == "" { + log.Error("could not find the managed application name on the resource") + return rs.SetMessage("managed application name not found").Failed() + } + + consumer, err := a.client.CreateConsumer(a.ctx, a.appID, a.appName) + if err != nil { + a.logger.WithError(err).Error("error creating kong consumer") + return rs.SetMessage("could not create a new consumer in kong").Failed() + } + + rs.AddProperty(common.AttrAppID, *consumer.ID) + a.logger.Info("created application") + + return rs.Success() +} + +func (a AppProvisioner) Deprovision() provisioning.RequestStatus { + a.logger.Info("deprovisioning application") + + rs := provisioning.NewRequestStatusBuilder() + + if a.consumerID == "" { + log.Error("could not find the consumer id on the managed application resource") + return rs.SetMessage(fmt.Sprintf("%s not found", common.AttrAppID)).Failed() + } + + err := a.client.DeleteConsumer(a.ctx, a.consumerID) + if err != nil { + a.logger.WithError(err).Error("error deleting kong consumer") + return rs.SetMessage("could not remove consumer in kong").Failed() + } + a.logger.Info("removed application") + + return rs.Success() +} diff --git a/pkg/subscription/application/application_test.go b/pkg/subscription/application/application_test.go new file mode 100644 index 0000000..8cc1754 --- /dev/null +++ b/pkg/subscription/application/application_test.go @@ -0,0 +1,158 @@ +package application + +import ( + "context" + "fmt" + "testing" + + "github.com/Axway/agent-sdk/pkg/apic/provisioning" + "github.com/Axway/agents-kong/pkg/common" + "github.com/google/uuid" + klib "github.com/kong/go-kong/kong" + "github.com/stretchr/testify/assert" +) + +type mockAppClient struct { + createErr bool + deleteErr bool + consumer *klib.Consumer +} + +func (m mockAppClient) CreateConsumer(ctx context.Context, id, name string) (*klib.Consumer, error) { + if m.createErr { + return nil, fmt.Errorf("error") + } + return m.consumer, nil +} + +func (m mockAppClient) DeleteConsumer(ctx context.Context, id string) error { + if m.deleteErr { + return fmt.Errorf("error") + } + return nil +} + +type mockApplicationRequest struct { + values map[string]string + name string + id string + team string +} + +func (m mockApplicationRequest) GetApplicationDetailsValue(key string) string { + if m.values == nil { + return "" + } + if val, ok := m.values[key]; ok { + return val + } + return "" +} + +func (m mockApplicationRequest) GetManagedApplicationName() string { + return m.name +} + +func (m mockApplicationRequest) GetTeamName() string { + return m.team +} + +func (m mockApplicationRequest) GetID() string { + return m.id +} + +func TestProvision(t *testing.T) { + testCases := map[string]struct { + client mockAppClient + request mockApplicationRequest + expectStatus provisioning.Status + }{ + "expect error when no app name set": { + request: mockApplicationRequest{ + id: "appID", + }, + expectStatus: provisioning.Error, + }, + "expect error when create consumer fails": { + client: mockAppClient{ + createErr: true, + }, + request: mockApplicationRequest{ + name: "appName", + id: "appID", + }, + expectStatus: provisioning.Error, + }, + "success when provisioning a managed application": { + client: mockAppClient{ + consumer: &klib.Consumer{ + ID: klib.String(uuid.NewString()), + }, + }, + request: mockApplicationRequest{ + name: "appName", + id: "appID", + }, + expectStatus: provisioning.Success, + }, + } + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + ctx := context.WithValue(context.Background(), "testName", name) + + result := NewApplicationProvisioner(ctx, tc.client, &tc.request).Provision() + assert.Equal(t, tc.expectStatus, result.GetStatus()) + if tc.expectStatus == provisioning.Success { + // validate consumerID set + val, ok := result.GetProperties()[common.AttrAppID] + assert.True(t, ok) + assert.Equal(t, *tc.client.consumer.ID, val) + } + }) + } +} + +func TestDeleteConsumer(t *testing.T) { + testCases := map[string]struct { + client mockAppClient + request mockApplicationRequest + expectStatus provisioning.Status + }{ + "expect error when no consumer id set": { + request: mockApplicationRequest{}, + expectStatus: provisioning.Error, + }, + "expect error when delete consumer fails": { + client: mockAppClient{ + deleteErr: true, + }, + request: mockApplicationRequest{ + name: "appName", + id: "appID", + values: map[string]string{ + common.AttrAppID: "consumerID", + }, + }, + expectStatus: provisioning.Error, + }, + "success deprovisioning a managed application": { + client: mockAppClient{}, + request: mockApplicationRequest{ + name: "appName", + id: "appID", + values: map[string]string{ + common.AttrAppID: "consumerID", + }, + }, + expectStatus: provisioning.Success, + }, + } + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + ctx := context.WithValue(context.Background(), "testName", name) + + result := NewApplicationProvisioner(ctx, tc.client, &tc.request).Deprovision() + assert.Equal(t, tc.expectStatus, result.GetStatus()) + }) + } +} diff --git a/pkg/subscription/provision.go b/pkg/subscription/provision.go index dbabe69..cc952f1 100644 --- a/pkg/subscription/provision.go +++ b/pkg/subscription/provision.go @@ -15,6 +15,7 @@ import ( "github.com/Axway/agents-kong/pkg/common" "github.com/Axway/agents-kong/pkg/kong" + "github.com/Axway/agents-kong/pkg/subscription/application" ) var constructors []func(*klib.Client) Handler @@ -230,3 +231,11 @@ func GetProvisionKeyPropertyBuilder() provisioning.PropertyBuilder { // } // return nil //} + +func (p provisioner) ApplicationRequestProvision(request provisioning.ApplicationRequest) provisioning.RequestStatus { + return application.NewApplicationProvisioner(context.Background(), p.client, request).Provision() +} + +func (p provisioner) ApplicationRequestDeprovision(request provisioning.ApplicationRequest) provisioning.RequestStatus { + return application.NewApplicationProvisioner(context.Background(), p.client, request).Deprovision() +} From a6885e58a009dc4f66e3629e1c511c3f6fc091f7 Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Wed, 1 Nov 2023 14:20:56 -0700 Subject: [PATCH 60/76] add codeowners --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..a7b514d --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +* @jcollins @sbolosan @vchauhan @acrosca @dgghinea \ No newline at end of file From 3fb8371f9e83807fd02112b7c3f5da4c5e17686f Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Wed, 1 Nov 2023 14:24:59 -0700 Subject: [PATCH 61/76] update --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index a7b514d..3a38ec9 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1 @@ -* @jcollins @sbolosan @vchauhan @acrosca @dgghinea \ No newline at end of file +* @jcollins-axway @sbolosan @vivekschauhan @alrosca @dgghinea \ No newline at end of file From b9bff073e97c338aeffbf772973d4341c839e07a Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Thu, 2 Nov 2023 14:56:54 +0200 Subject: [PATCH 62/76] APIGOV-26571 set context for every discovery trigger --- pkg/cmd/discovery/discoveryCmd.go | 4 +++- pkg/gateway/client.go | 11 +++++------ pkg/gateway/definitions.go | 3 --- pkg/kong/kongclient.go | 1 + 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/pkg/cmd/discovery/discoveryCmd.go b/pkg/cmd/discovery/discoveryCmd.go index 9900469..b4a3902 100644 --- a/pkg/cmd/discovery/discoveryCmd.go +++ b/pkg/cmd/discovery/discoveryCmd.go @@ -1,6 +1,7 @@ package discovery import ( + "context" "time" corecmd "github.com/Axway/agent-sdk/pkg/cmd" @@ -46,7 +47,8 @@ func run() error { go func() { for { - err = gatewayClient.DiscoverAPIs() + ctx := context.Background() + err = gatewayClient.DiscoverAPIs(ctx) if err != nil { log.Errorf("error in processing: %v", err) stopChan <- struct{}{} diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 823e6ac..fc27039 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -58,7 +58,6 @@ func NewClient(agentConfig config.AgentConfig) (*Client, error) { } subscription.NewProvisioner(kongClient.Client, logger) return &Client{ - ctx: context.Background(), logger: logger, centralCfg: agentConfig.CentralCfg, kongGatewayCfg: kongGatewayConfig, @@ -79,28 +78,28 @@ func findACLGroup(groups []interface{}) string { return "" } -func (gc *Client) DiscoverAPIs() error { +func (gc *Client) DiscoverAPIs(ctx context.Context) error { gc.logger.Info("execute discovery process") plugins := kutil.Plugins{PluginLister: gc.kongClient.GetKongPlugins()} gc.plugins = plugins - services, err := gc.kongClient.ListServices(gc.ctx) + services, err := gc.kongClient.ListServices(ctx) if err != nil { gc.logger.WithError(err).Error("failed to get services") return err } - gc.processKongServicesList(services) + gc.processKongServicesList(ctx, services) return nil } -func (gc *Client) processKongServicesList(services []*klib.Service) { +func (gc *Client) processKongServicesList(ctx context.Context, services []*klib.Service) { wg := new(sync.WaitGroup) for _, service := range services { wg.Add(1) go func(service *klib.Service, wg *sync.WaitGroup) { defer wg.Done() - err := gc.processSingleKongService(gc.ctx, service) + err := gc.processSingleKongService(ctx, service) if err != nil { log.Error(err) } diff --git a/pkg/gateway/definitions.go b/pkg/gateway/definitions.go index 19d04da..b9846d5 100644 --- a/pkg/gateway/definitions.go +++ b/pkg/gateway/definitions.go @@ -1,8 +1,6 @@ package gateway import ( - "context" - "github.com/Axway/agent-sdk/pkg/apic" "github.com/Axway/agent-sdk/pkg/cache" corecfg "github.com/Axway/agent-sdk/pkg/config" @@ -14,7 +12,6 @@ import ( ) type Client struct { - ctx context.Context logger logrus.FieldLogger centralCfg corecfg.CentralConfig kongGatewayCfg *config.KongGatewayConfig diff --git a/pkg/kong/kongclient.go b/pkg/kong/kongclient.go index 2b87fb0..c4dd9d0 100644 --- a/pkg/kong/kongclient.go +++ b/pkg/kong/kongclient.go @@ -23,6 +23,7 @@ type KongAPIClient interface { type KongClient struct { *klib.Client + ctx context.Context logger logrus.FieldLogger baseClient DoRequest kongAdminEndpoint string From 17e55128cbb91712e6bb19d920342fa0a0e439f7 Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Thu, 2 Nov 2023 14:58:37 +0200 Subject: [PATCH 63/76] APIGOV-26571 context created in discovery func --- pkg/cmd/discovery/discoveryCmd.go | 4 +--- pkg/gateway/client.go | 4 +++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/cmd/discovery/discoveryCmd.go b/pkg/cmd/discovery/discoveryCmd.go index b4a3902..9900469 100644 --- a/pkg/cmd/discovery/discoveryCmd.go +++ b/pkg/cmd/discovery/discoveryCmd.go @@ -1,7 +1,6 @@ package discovery import ( - "context" "time" corecmd "github.com/Axway/agent-sdk/pkg/cmd" @@ -47,8 +46,7 @@ func run() error { go func() { for { - ctx := context.Background() - err = gatewayClient.DiscoverAPIs(ctx) + err = gatewayClient.DiscoverAPIs() if err != nil { log.Errorf("error in processing: %v", err) stopChan <- struct{}{} diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index fc27039..13d93db 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -78,9 +78,11 @@ func findACLGroup(groups []interface{}) string { return "" } -func (gc *Client) DiscoverAPIs(ctx context.Context) error { +func (gc *Client) DiscoverAPIs() error { gc.logger.Info("execute discovery process") + ctx := context.Background() + plugins := kutil.Plugins{PluginLister: gc.kongClient.GetKongPlugins()} gc.plugins = plugins services, err := gc.kongClient.ListServices(ctx) From f83165490fbe875e143d6db89952f3dfe243e165 Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Thu, 2 Nov 2023 15:27:18 +0200 Subject: [PATCH 64/76] APIGOV-26571 use agent sdk log package --- pkg/gateway/client.go | 25 +++++++++++++------------ pkg/gateway/definitions.go | 4 ++-- pkg/subscription/provision.go | 5 +++-- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 13d93db..0b31b38 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -36,10 +36,7 @@ func NewClient(agentConfig config.AgentConfig) (*Client, error) { } apicClient := NewCentralClient(agent.GetCentralClient(), agentConfig.CentralCfg) daCache := cache.New() - logger := logrus.WithFields(logrus.Fields{ - "component": "agent", - "package": "discovery", - }) + logger := log.NewFieldLogger().WithComponent("discovery").WithPackage("kong") plugins, err := kongClient.Plugins.ListAll(context.Background()) if err != nil { @@ -56,7 +53,10 @@ func NewClient(agentConfig config.AgentConfig) (*Client, error) { } } } - subscription.NewProvisioner(kongClient.Client, logger) + + provisionLogger := log.NewFieldLogger().WithComponent("provision").WithPackage("kong") + subscription.NewProvisioner(kongClient.Client, provisionLogger) + return &Client{ logger: logger, centralCfg: agentConfig.CentralCfg, @@ -111,7 +111,8 @@ func (gc *Client) processKongServicesList(ctx context.Context, services []*klib. } func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Service) error { - gc.logger.Infof("processing service %s", *service.Name) + log := gc.logger.WithField("service-name", *service.Name) + log.Infof("processing service %s", *service.Name) proxyEndpoint := gc.kongGatewayCfg.ProxyEndpoint httpPort := gc.kongGatewayCfg.ProxyHttpPort @@ -119,7 +120,7 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se routes, err := gc.kongClient.ListRoutesForService(ctx, *service.ID) if err != nil { - gc.logger.WithError(err).Errorf("failed to get routes for service %s", *service.Name) + log.WithError(err).Errorf("failed to get routes for service %s", *service.Name) return err } if len(routes) == 0 { @@ -131,13 +132,13 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se apiPlugins, err := gc.plugins.GetEffectivePlugins(*route.ID, *service.ID) if err != nil { - gc.logger.WithError(err).Errorf("failed to get plugins for route %s", *route.ID) + log.WithError(err).Errorf("failed to get plugins for route %s", *route.ID) return err } kongServiceSpec, err := gc.kongClient.GetSpecForService(ctx, *service.Host) if err != nil { - gc.logger.WithError(err).Errorf("failed to get spec for service %s", *service.Name) + log.WithError(err).Errorf("failed to get spec for service %s", *service.Name) return err } @@ -150,16 +151,16 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se return err } if serviceBody == nil { - gc.logger.Debugf("not processing '%s' since no changes were detected", *service.Name) + log.Debugf("not processing '%s' since no changes were detected", *service.Name) return nil } err = agent.PublishAPI(*serviceBody) if err != nil { - gc.logger.WithError(err).Error("failed to publish api") + log.WithError(err).Error("failed to publish api") return err } - gc.logger.Infof("Published API '%s' to central", serviceBody.APIName) + log.Infof("Published API '%s' to central", serviceBody.APIName) return nil } diff --git a/pkg/gateway/definitions.go b/pkg/gateway/definitions.go index b9846d5..1891f10 100644 --- a/pkg/gateway/definitions.go +++ b/pkg/gateway/definitions.go @@ -4,15 +4,15 @@ import ( "github.com/Axway/agent-sdk/pkg/apic" "github.com/Axway/agent-sdk/pkg/cache" corecfg "github.com/Axway/agent-sdk/pkg/config" + "github.com/Axway/agent-sdk/pkg/util/log" "github.com/Axway/agents-kong/pkg/kong" - "github.com/sirupsen/logrus" config "github.com/Axway/agents-kong/pkg/config/discovery" kutil "github.com/Axway/agents-kong/pkg/kong" ) type Client struct { - logger logrus.FieldLogger + logger log.FieldLogger centralCfg corecfg.CentralConfig kongGatewayCfg *config.KongGatewayConfig kongClient kong.KongAPIClient diff --git a/pkg/subscription/provision.go b/pkg/subscription/provision.go index b8a0be8..56444f2 100644 --- a/pkg/subscription/provision.go +++ b/pkg/subscription/provision.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/apic/provisioning" "github.com/Axway/agent-sdk/pkg/util" @@ -30,12 +31,12 @@ type Handler interface { type provisioner struct { kc *kong.Client - log logrus.FieldLogger + log log.FieldLogger handlers map[string]Handler } // NewProvisioner creates a type to implement the SDK Provisioning methods for handling subscriptions -func NewProvisioner(kc *kong.Client, log logrus.FieldLogger) { +func NewProvisioner(kc *kong.Client, log log.FieldLogger) { logrus.Info("Registering provisioning callbacks") logrus.Infof("Handlers : %d", len(constructors)) handlers := make(map[string]Handler, len(constructors)) From 138e7e3671a43ab5f893c3bcc1e461cd489fe7dd Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Thu, 2 Nov 2023 15:28:25 +0200 Subject: [PATCH 65/76] APIGOV-26571 get spec func --- pkg/kong/kongclient.go | 72 +++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/pkg/kong/kongclient.go b/pkg/kong/kongclient.go index c4dd9d0..e1862ec 100644 --- a/pkg/kong/kongclient.go +++ b/pkg/kong/kongclient.go @@ -8,8 +8,8 @@ import ( "time" "github.com/Axway/agent-sdk/pkg/apic" + "github.com/Axway/agent-sdk/pkg/util/log" config "github.com/Axway/agents-kong/pkg/config/discovery" - "github.com/sirupsen/logrus" klib "github.com/kong/go-kong/kong" ) @@ -24,7 +24,7 @@ type KongAPIClient interface { type KongClient struct { *klib.Client ctx context.Context - logger logrus.FieldLogger + logger log.FieldLogger baseClient DoRequest kongAdminEndpoint string specPaths []string @@ -42,10 +42,7 @@ func NewKongClient(baseClient *http.Client, kongConfig *config.KongGatewayConfig baseClient = client } - logger := logrus.WithFields(logrus.Fields{ - "component": "agent", - "package": "discovery", - }) + logger := log.NewFieldLogger().WithComponent("discovery").WithPackage("kong") baseKongClient, err := klib.NewClient(&kongConfig.AdminEndpoint, baseClient) if err != nil { @@ -77,41 +74,52 @@ func (k KongClient) GetSpecForService(ctx context.Context, backendURL string) ([ return nil, nil } - ctxTimeout, cancel := context.WithTimeout(ctx, k.clientTimeout) - defer cancel() - - var specContent []byte - for _, specPath := range k.specPaths { endpoint := fmt.Sprintf("%s/%s", backendURL, specPath) - req, err := http.NewRequestWithContext(ctxTimeout, "GET", endpoint, nil) - if err != nil { - k.logger.WithError(err).Error("failed to create request") - return nil, err - } - res, err := k.baseClient.Do(req) + + spec, err := k.getSpec(ctx, endpoint) if err != nil { - k.logger.WithError(err).Error("failed to execute request") return nil, err } - if res.StatusCode != http.StatusOK { + if spec == nil { continue } + return spec, nil + } - specContent, err = io.ReadAll(res.Body) - if err != nil { - k.logger.WithError(err).Error("failed to read body") - return nil, err - } + k.logger.Info("no spec found") + return []byte{}, nil +} - specParser := apic.NewSpecResourceParser(specContent, "") - err = specParser.Parse() - if err != nil { - k.logger.Debug("invalid api spec") - continue - } - // break if spec is validated - break +func (k KongClient) getSpec(ctx context.Context, endpoint string) ([]byte, error) { + ctxTimeout, cancel := context.WithTimeout(ctx, k.clientTimeout) + defer cancel() + + req, err := http.NewRequestWithContext(ctxTimeout, "GET", endpoint, nil) + if err != nil { + k.logger.WithError(err).Error("failed to create request") + return nil, err + } + res, err := k.baseClient.Do(req) + if err != nil { + k.logger.WithError(err).Error("failed to execute request") + return nil, err + } + if res.StatusCode != http.StatusOK { + return nil, nil + } + + specContent, err := io.ReadAll(res.Body) + if err != nil { + k.logger.WithError(err).Error("failed to read body") + return nil, err + } + + specParser := apic.NewSpecResourceParser(specContent, "") + err = specParser.Parse() + if err != nil { + k.logger.Debug("invalid api spec") + return nil, nil } return specContent, nil From b0da786342a562ab63dde9ea62c07e7abc9a1881 Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Thu, 2 Nov 2023 15:28:48 +0200 Subject: [PATCH 66/76] APIGOV-26571 change import name --- pkg/processor/eventmapper.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/processor/eventmapper.go b/pkg/processor/eventmapper.go index be3ec21..61968f2 100644 --- a/pkg/processor/eventmapper.go +++ b/pkg/processor/eventmapper.go @@ -11,7 +11,7 @@ import ( "github.com/Axway/agent-sdk/pkg/agent" "github.com/Axway/agent-sdk/pkg/transaction" - "github.com/Axway/agent-sdk/pkg/transaction/util" + sdkUtil "github.com/Axway/agent-sdk/pkg/transaction/util" "github.com/Axway/agent-sdk/pkg/util/log" ) @@ -158,12 +158,12 @@ func (m *EventMapper) createSummaryEvent(ktle KongTrafficLogEntry, teamID string ktle.Request.URI, ktle.Request.URL). SetDuration(ktle.Latencies.Request). - SetProxy(util.FormatProxyID(ktle.Route.ID), + SetProxy(sdkUtil.FormatProxyID(ktle.Route.ID), ktle.Service.Name, 1) if ktle.Consumer != nil { - builder.SetApplication(util.FormatApplicationID(ktle.Consumer.ID), ktle.Consumer.Username) + builder.SetApplication(sdkUtil.FormatApplicationID(ktle.Consumer.ID), ktle.Consumer.Username) } return builder.Build() From b3caf228041e39dd1c8504e0ce42ff4653928043 Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Thu, 2 Nov 2023 06:43:13 -0700 Subject: [PATCH 67/76] review comments and cleanup --- go.mod | 17 ++++----- go.sum | 35 ++++++++++++------- pkg/subscription/application/application.go | 10 +++++- .../application/application_test.go | 12 +++---- 4 files changed, 45 insertions(+), 29 deletions(-) diff --git a/go.mod b/go.mod index e5cd624..f9d821a 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Axway/agents-kong go 1.18 require ( - github.com/Axway/agent-sdk v1.1.58 + github.com/Axway/agent-sdk v1.1.66 github.com/elastic/beats/v7 v7.17.5 github.com/google/uuid v1.3.0 github.com/kong/go-kong v0.46.0 @@ -88,11 +88,11 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/kong/semver/v4 v4.0.1 // indirect - github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect github.com/lestrrat-go/blackmagic v1.0.1 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect + github.com/lestrrat-go/httprc v1.0.4 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect - github.com/lestrrat-go/jwx v1.2.26 // indirect + github.com/lestrrat-go/jwx/v2 v2.0.12 // indirect github.com/lestrrat-go/option v1.0.1 // indirect github.com/magefile/mage v1.13.0 // indirect github.com/magiconair/properties v1.8.6 // indirect @@ -114,6 +114,7 @@ require ( github.com/prometheus/procfs v0.7.3 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect + github.com/segmentio/asm v1.2.0 // indirect github.com/shirou/gopsutil v3.20.12+incompatible // indirect github.com/snowzach/rotatefilehook v0.0.0-20220211133110-53752135082d // indirect github.com/spf13/afero v1.8.2 // indirect @@ -139,14 +140,14 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect go.uber.org/zap v1.21.0 // indirect - golang.org/x/crypto v0.9.0 // indirect + golang.org/x/crypto v0.14.0 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect golang.org/x/mod v0.9.0 // indirect - golang.org/x/net v0.10.0 // indirect + golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/term v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect golang.org/x/tools v0.7.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index cbb6b1b..67ded47 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Axway/agent-sdk v1.1.58 h1:wnrnuRKus/aZPLhOPZr8FiCPbCQ4VJBra/Gp7iVFdbs= -github.com/Axway/agent-sdk v1.1.58/go.mod h1:xe6dIpQxE0LcSR+ssGKL4mfyLFbrLohdrB9iMYFUCdU= +github.com/Axway/agent-sdk v1.1.66 h1:7kdbG/ZRnkEyEbN59nPPkNxCRprmWboYet30GQ6DjAw= +github.com/Axway/agent-sdk v1.1.66/go.mod h1:8q45LmNi+phajNNcByYMNEJfI7NhYYoL+U7QDaqwfQY= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= @@ -372,16 +372,16 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= -github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80= github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= +github.com/lestrrat-go/httprc v1.0.4 h1:bAZymwoZQb+Oq8MEbyipag7iSq6YIga8Wj6GOiJGdI8= +github.com/lestrrat-go/httprc v1.0.4/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo= github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx v1.2.26 h1:4iFo8FPRZGDYe1t19mQP0zTRqA7n8HnJ5lkIiDvJcB0= -github.com/lestrrat-go/jwx v1.2.26/go.mod h1:MaiCdGbn3/cckbOFSCluJlJMmp9dmZm5hDuIkx8ftpQ= +github.com/lestrrat-go/jwx/v2 v2.0.12 h1:3d589+5w/b9b7S3DneICPW16AqTyYXB7VRjgluSDWeA= +github.com/lestrrat-go/jwx/v2 v2.0.12/go.mod h1:Mq4KN1mM7bp+5z/W5HS8aCNs5RKZ911G/0y2qUjAQuQ= github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= @@ -456,6 +456,8 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis= github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4= +github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= +github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/shirou/gopsutil v3.20.12+incompatible h1:6VEGkOXP/eP4o2Ilk8cSsX0PhOEfX6leqAnD+urrp9M= github.com/shirou/gopsutil v3.20.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -574,8 +576,9 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= 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= @@ -660,8 +663,9 @@ golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= 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= @@ -749,15 +753,18 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= 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= @@ -767,8 +774,10 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 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= diff --git a/pkg/subscription/application/application.go b/pkg/subscription/application/application.go index f6ed781..7161916 100644 --- a/pkg/subscription/application/application.go +++ b/pkg/subscription/application/application.go @@ -22,6 +22,14 @@ type appClient interface { DeleteConsumer(ctx context.Context, id string) error } +type appRequest interface { + GetApplicationDetailsValue(key string) string + // GetManagedApplicationName returns the name of the managed application for this credential + GetManagedApplicationName() string + // GetID returns the ID of the resource for the request + GetID() string +} + type AppProvisioner struct { ctx context.Context logger log.FieldLogger @@ -31,7 +39,7 @@ type AppProvisioner struct { consumerID string } -func NewApplicationProvisioner(ctx context.Context, client appClient, request provisioning.ApplicationRequest) AppProvisioner { +func NewApplicationProvisioner(ctx context.Context, client appClient, request appRequest) AppProvisioner { a := AppProvisioner{ ctx: context.Background(), logger: log.NewFieldLogger(). diff --git a/pkg/subscription/application/application_test.go b/pkg/subscription/application/application_test.go index 8cc1754..f9b5e26 100644 --- a/pkg/subscription/application/application_test.go +++ b/pkg/subscription/application/application_test.go @@ -6,12 +6,15 @@ import ( "testing" "github.com/Axway/agent-sdk/pkg/apic/provisioning" + "github.com/Axway/agent-sdk/pkg/util/log" "github.com/Axway/agents-kong/pkg/common" "github.com/google/uuid" klib "github.com/kong/go-kong/kong" "github.com/stretchr/testify/assert" ) +const testName log.ContextField = "testName" + type mockAppClient struct { createErr bool deleteErr bool @@ -36,7 +39,6 @@ type mockApplicationRequest struct { values map[string]string name string id string - team string } func (m mockApplicationRequest) GetApplicationDetailsValue(key string) string { @@ -53,10 +55,6 @@ func (m mockApplicationRequest) GetManagedApplicationName() string { return m.name } -func (m mockApplicationRequest) GetTeamName() string { - return m.team -} - func (m mockApplicationRequest) GetID() string { return m.id } @@ -98,7 +96,7 @@ func TestProvision(t *testing.T) { } for name, tc := range testCases { t.Run(name, func(t *testing.T) { - ctx := context.WithValue(context.Background(), "testName", name) + ctx := context.WithValue(context.Background(), testName, name) result := NewApplicationProvisioner(ctx, tc.client, &tc.request).Provision() assert.Equal(t, tc.expectStatus, result.GetStatus()) @@ -149,7 +147,7 @@ func TestDeleteConsumer(t *testing.T) { } for name, tc := range testCases { t.Run(name, func(t *testing.T) { - ctx := context.WithValue(context.Background(), "testName", name) + ctx := context.WithValue(context.Background(), testName, name) result := NewApplicationProvisioner(ctx, tc.client, &tc.request).Deprovision() assert.Equal(t, tc.expectStatus, result.GetStatus()) From 03a02713a9913caf60ff9d2876c1ae03dfdd9e8e Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Thu, 2 Nov 2023 15:52:53 +0200 Subject: [PATCH 68/76] APIGOV-26571 update logger component --- pkg/kong/kongclient.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/kong/kongclient.go b/pkg/kong/kongclient.go index e1862ec..d5da353 100644 --- a/pkg/kong/kongclient.go +++ b/pkg/kong/kongclient.go @@ -42,7 +42,7 @@ func NewKongClient(baseClient *http.Client, kongConfig *config.KongGatewayConfig baseClient = client } - logger := log.NewFieldLogger().WithComponent("discovery").WithPackage("kong") + logger := log.NewFieldLogger().WithComponent("client").WithPackage("kong") baseKongClient, err := klib.NewClient(&kongConfig.AdminEndpoint, baseClient) if err != nil { From 5006f7d451ffbcd3e3ebb7bf44c2812b56baf9a9 Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Thu, 2 Nov 2023 15:54:05 +0200 Subject: [PATCH 69/76] APIGOV-26571 update kong default config --- default_kong_discovery_agent.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/default_kong_discovery_agent.yml b/default_kong_discovery_agent.yml index d1f28ce..015e080 100644 --- a/default_kong_discovery_agent.yml +++ b/default_kong_discovery_agent.yml @@ -28,5 +28,4 @@ kong: proxyEndpointProtocols: http: 80 https: 443 - specDevPortalEnabled: - specHomePath: + specDownloadPaths: [] From 00dd9e27a3f2a40069596e858d92a728a1b48673 Mon Sep 17 00:00:00 2001 From: Jason Collins Date: Thu, 2 Nov 2023 11:24:40 -0700 Subject: [PATCH 70/76] add ACL and fix code based off tests --- pkg/kong/kongclient.go | 1 + pkg/kong/provisioning.go | 31 +++++++++- pkg/kong/provisioning_test.go | 58 +++++++++++++++++++ pkg/subscription/application/application.go | 14 +++-- .../application/application_test.go | 21 +++++++ 5 files changed, 119 insertions(+), 6 deletions(-) diff --git a/pkg/kong/kongclient.go b/pkg/kong/kongclient.go index 502399b..e779525 100644 --- a/pkg/kong/kongclient.go +++ b/pkg/kong/kongclient.go @@ -18,6 +18,7 @@ import ( type KongAPIClient interface { // Provisioning CreateConsumer(ctx context.Context, id, name string) (*klib.Consumer, error) + AddConsumerACL(ctx context.Context, id string) error DeleteConsumer(ctx context.Context, id string) error ListServices(ctx context.Context) ([]*klib.Service, error) diff --git a/pkg/kong/provisioning.go b/pkg/kong/provisioning.go index 90a49ee..0d7dafe 100644 --- a/pkg/kong/provisioning.go +++ b/pkg/kong/provisioning.go @@ -16,10 +16,37 @@ func (k KongClient) CreateConsumer(ctx context.Context, id, name string) (*klib. } log.Debug("creating new consumer") - return k.Consumers.Create(ctx, &klib.Consumer{ + consumer, err = k.Consumers.Create(ctx, &klib.Consumer{ CustomID: klib.String(id), Username: klib.String(name), }) + if err != nil { + log.WithError(err).Error("creating consumer") + return nil, err + } + + return consumer, nil +} + +func (k KongClient) AddConsumerACL(ctx context.Context, id string) error { + log := k.logger.WithField("consumerID", id) + consumer, err := k.Consumers.Get(ctx, klib.String(id)) + if err != nil { + log.Debug("could not find consumer") + return err + } + + log.Debug("adding consumer acl") + _, err = k.ACLs.Create(ctx, consumer.ID, &klib.ACLGroup{ + Consumer: consumer, + Group: klib.String(id), + }) + + if err != nil { + log.WithError(err).Error("adding acl to consumer") + return err + } + return nil } func (k KongClient) DeleteConsumer(ctx context.Context, id string) error { @@ -27,7 +54,7 @@ func (k KongClient) DeleteConsumer(ctx context.Context, id string) error { log := k.logger.WithField("consumerID", id) _, err := k.Consumers.Get(ctx, klib.String(id)) if err != nil { - log.Debug("could not get consumer") + log.Debug("could not find consumer") return nil } diff --git a/pkg/kong/provisioning_test.go b/pkg/kong/provisioning_test.go index 6a9a1fe..a079458 100644 --- a/pkg/kong/provisioning_test.go +++ b/pkg/kong/provisioning_test.go @@ -111,6 +111,64 @@ func TestCreateConsumer(t *testing.T) { } } +func TestAddConsumerACL(t *testing.T) { + testCases := map[string]struct { + expectErr bool + responses map[string]response + }{ + "consumer does not exist": { + expectErr: true, + responses: map[string]response{ + formatRequestKey(http.MethodGet, "/consumers/id"): { + code: http.StatusNotFound, + }, + }, + }, + "add consumer acl": { + expectErr: false, + responses: map[string]response{ + formatRequestKey(http.MethodGet, "/consumers/id"): { + code: http.StatusOK, + dataIface: &klib.Consumer{ + ID: klib.String("id"), + Username: klib.String("name"), + }, + }, + formatRequestKey(http.MethodPost, "/consumers/id/acls"): { + code: http.StatusOK, + dataIface: &klib.ACLGroup{}, + }, + }, + }, + "add consumer acl error": { + expectErr: true, + responses: map[string]response{ + formatRequestKey(http.MethodGet, "/consumers/id"): { + code: http.StatusOK, + dataIface: &klib.Consumer{ + ID: klib.String("id"), + Username: klib.String("name"), + }, + }, + formatRequestKey(http.MethodPost, "/consumers/id/acls"): { + code: http.StatusBadRequest, + }, + }, + }, + } + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + client := createClient(tc.responses) + err := client.AddConsumerACL(context.TODO(), "id") + if tc.expectErr { + assert.NotNil(t, err) + return + } + assert.Nil(t, err) + }) + } +} + func TestDeleteConsumer(t *testing.T) { testCases := map[string]struct { expectErr bool diff --git a/pkg/subscription/application/application.go b/pkg/subscription/application/application.go index 7161916..17cc957 100644 --- a/pkg/subscription/application/application.go +++ b/pkg/subscription/application/application.go @@ -19,6 +19,7 @@ const ( type appClient interface { CreateConsumer(ctx context.Context, id, name string) (*klib.Consumer, error) + AddConsumerACL(ctx context.Context, id string) error DeleteConsumer(ctx context.Context, id string) error } @@ -67,7 +68,7 @@ func (a AppProvisioner) Provision() provisioning.RequestStatus { rs := provisioning.NewRequestStatusBuilder() if a.appName == "" { - log.Error("could not find the managed application name on the resource") + a.logger.Error("could not find the managed application name on the resource") return rs.SetMessage("managed application name not found").Failed() } @@ -77,8 +78,13 @@ func (a AppProvisioner) Provision() provisioning.RequestStatus { return rs.SetMessage("could not create a new consumer in kong").Failed() } + err = a.client.AddConsumerACL(a.ctx, *consumer.ID) + if err != nil { + a.logger.WithError(err).Error("could not add acl to kong consumer") + } + rs.AddProperty(common.AttrAppID, *consumer.ID) - a.logger.Info("created application") + a.logger.Info("provisioned application") return rs.Success() } @@ -89,7 +95,7 @@ func (a AppProvisioner) Deprovision() provisioning.RequestStatus { rs := provisioning.NewRequestStatusBuilder() if a.consumerID == "" { - log.Error("could not find the consumer id on the managed application resource") + a.logger.Error("could not find the consumer id on the managed application resource") return rs.SetMessage(fmt.Sprintf("%s not found", common.AttrAppID)).Failed() } @@ -98,7 +104,7 @@ func (a AppProvisioner) Deprovision() provisioning.RequestStatus { a.logger.WithError(err).Error("error deleting kong consumer") return rs.SetMessage("could not remove consumer in kong").Failed() } - a.logger.Info("removed application") + a.logger.Info("deprovisioned application") return rs.Success() } diff --git a/pkg/subscription/application/application_test.go b/pkg/subscription/application/application_test.go index f9b5e26..3039b45 100644 --- a/pkg/subscription/application/application_test.go +++ b/pkg/subscription/application/application_test.go @@ -18,6 +18,7 @@ const testName log.ContextField = "testName" type mockAppClient struct { createErr bool deleteErr bool + addACLErr bool consumer *klib.Consumer } @@ -28,6 +29,13 @@ func (m mockAppClient) CreateConsumer(ctx context.Context, id, name string) (*kl return m.consumer, nil } +func (m mockAppClient) AddConsumerACL(ctx context.Context, id string) error { + if m.addACLErr { + return fmt.Errorf("error") + } + return nil +} + func (m mockAppClient) DeleteConsumer(ctx context.Context, id string) error { if m.deleteErr { return fmt.Errorf("error") @@ -81,6 +89,19 @@ func TestProvision(t *testing.T) { }, expectStatus: provisioning.Error, }, + "success when provisioning a managed application even when acl call fails": { + client: mockAppClient{ + addACLErr: true, + consumer: &klib.Consumer{ + ID: klib.String(uuid.NewString()), + }, + }, + request: mockApplicationRequest{ + name: "appName", + id: "appID", + }, + expectStatus: provisioning.Success, + }, "success when provisioning a managed application": { client: mockAppClient{ consumer: &klib.Consumer{ From 78f9ca07b28c2e2697eac13586bca7c4288ee413 Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Fri, 3 Nov 2023 14:49:22 +0200 Subject: [PATCH 71/76] APIGOV-26571 add fields to logger --- pkg/gateway/client.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index a6a0ff7..3870159 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -105,7 +105,7 @@ func (gc *Client) processKongServicesList(ctx context.Context, services []*klib. func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Service) error { log := gc.logger.WithField("service-name", *service.Name) - log.Infof("processing service %s", *service.Name) + log.Infof("processing service") proxyEndpoint := gc.kongGatewayCfg.ProxyEndpoint httpPort := gc.kongGatewayCfg.ProxyHttpPort @@ -113,7 +113,7 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se routes, err := gc.kongClient.ListRoutesForService(ctx, *service.ID) if err != nil { - log.WithError(err).Errorf("failed to get routes for service %s", *service.Name) + log.WithError(err).Errorf("failed to get routes for service") return err } if len(routes) == 0 { @@ -122,16 +122,17 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se } route := routes[0] + log = log.WithField("route-id", *route.ID) apiPlugins, err := gc.plugins.GetEffectivePlugins(*route.ID, *service.ID) if err != nil { - log.WithError(err).Errorf("failed to get plugins for route %s", *route.ID) + log.WithError(err).Errorf("failed to get plugins for route") return err } kongServiceSpec, err := gc.kongClient.GetSpecForService(ctx, *service.Host) if err != nil { - log.WithError(err).Errorf("failed to get spec for service %s", *service.Name) + log.WithError(err).Errorf("failed to get spec for service") return err } @@ -144,7 +145,7 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se return err } if serviceBody == nil { - log.Debugf("not processing '%s' since no changes were detected", *service.Name) + log.Debugf("not processing since no changes were detected") return nil } err = agent.PublishAPI(*serviceBody) From e88439545a32b4db0f597ec70249aa771938bd81 Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Tue, 7 Nov 2023 15:17:08 +0200 Subject: [PATCH 72/76] APIGOV-26571 fix backend url --- pkg/gateway/client.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index 30cf8f6..f3d2da4 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -130,7 +130,9 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se return err } - kongServiceSpec, err := gc.kongClient.GetSpecForService(ctx, *service.Host) + backendURL := *service.Protocol + "://" + *service.Host + *service.Path + + kongServiceSpec, err := gc.kongClient.GetSpecForService(ctx, backendURL) if err != nil { log.WithError(err).Errorf("failed to get spec for service") return err From 0235b4a7cf92619320f959e860ff3235460f919f Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Thu, 9 Nov 2023 11:41:50 +0200 Subject: [PATCH 73/76] APIGOV-26571 check backend url fields --- pkg/gateway/client.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index f3d2da4..c1f7515 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -130,6 +130,12 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se return err } + // all three fields are needed to form the backend URL used in discovery process + if service.Protocol == nil && service.Host == nil && service.Path == nil { + err := fmt.Errorf("fields for backend URL are not set") + log.WithError(err).Error("failed to create backend URL") + return err + } backendURL := *service.Protocol + "://" + *service.Host + *service.Path kongServiceSpec, err := gc.kongClient.GetSpecForService(ctx, backendURL) From 5240967f78bb3e5d36e1af72eae250f5530b9186 Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Thu, 9 Nov 2023 11:41:50 +0200 Subject: [PATCH 74/76] APIGOV-26571 check backend url fields --- pkg/gateway/client.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index f3d2da4..c1f7515 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -130,6 +130,12 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se return err } + // all three fields are needed to form the backend URL used in discovery process + if service.Protocol == nil && service.Host == nil && service.Path == nil { + err := fmt.Errorf("fields for backend URL are not set") + log.WithError(err).Error("failed to create backend URL") + return err + } backendURL := *service.Protocol + "://" + *service.Host + *service.Path kongServiceSpec, err := gc.kongClient.GetSpecForService(ctx, backendURL) From 9dfa59d37958102c8df0d78c5506540101177844 Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Mon, 13 Nov 2023 15:53:20 +0200 Subject: [PATCH 75/76] delete test --- pkg/kong/provisioning_test.go | 51 ----------------------------------- 1 file changed, 51 deletions(-) diff --git a/pkg/kong/provisioning_test.go b/pkg/kong/provisioning_test.go index 6f4baff..a079458 100644 --- a/pkg/kong/provisioning_test.go +++ b/pkg/kong/provisioning_test.go @@ -11,7 +11,6 @@ import ( klib "github.com/kong/go-kong/kong" "github.com/stretchr/testify/assert" - "github.com/Axway/agents-kong/pkg/common" config "github.com/Axway/agents-kong/pkg/config/discovery" ) @@ -226,53 +225,3 @@ func TestDeleteConsumer(t *testing.T) { }) } } - -func TestAddManagedAppACL(t *testing.T) { - testCases := map[string]struct { - expectErr bool - consumerID string - routeID string - responses map[string]response - }{ - "find existing plugins": { - expectErr: false, - consumerID: "consumerID", - routeID: "routeID", - responses: map[string]response{ - formatRequestKey(http.MethodGet, "/plugins"): { - code: http.StatusOK, - dataIface: map[string]interface{}{ - "data": []*klib.Plugin{ - { - ID: klib.String("aclPluginID"), - Name: klib.String(common.AclPlugin), - Route: &klib.Route{ - ID: klib.String("routeID"), - }, - }, - }, - "next": "null", - }, - }, - formatRequestKey(http.MethodPatch, "/routes/routeID/plugins/aclPluginID"): { - code: http.StatusOK, - dataIface: &klib.Plugin{ - ID: klib.String("aclPluginID"), - Name: klib.String(common.AclPlugin), - }, - }, - }, - }, - } - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - client := createClient(tc.responses) - err := client.AddManagedAppACL(context.TODO(), tc.consumerID, tc.routeID) - if tc.expectErr { - assert.NotNil(t, err) - return - } - assert.Nil(t, err) - }) - } -} From 123432b1f57f7cd676f71c7c84ad00f404f36b7c Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Mon, 13 Nov 2023 15:56:09 +0200 Subject: [PATCH 76/76] APIGOV-26571 fix PR comm --- pkg/gateway/client.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index c1f7515..dba36cd 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -131,12 +131,15 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se } // all three fields are needed to form the backend URL used in discovery process - if service.Protocol == nil && service.Host == nil && service.Path == nil { + if service.Protocol == nil && service.Host == nil { err := fmt.Errorf("fields for backend URL are not set") log.WithError(err).Error("failed to create backend URL") return err } - backendURL := *service.Protocol + "://" + *service.Host + *service.Path + backendURL := *service.Protocol + "://" + *service.Host + if service.Path != nil { + backendURL = backendURL + *service.Path + } kongServiceSpec, err := gc.kongClient.GetSpecForService(ctx, backendURL) if err != nil {