Add Prometheus metrics (#10)
* Add Prometheus metrics - cleanup - update dependencies - improve parsing of options where possible - Update Go to latest version
This commit is contained in:
parent
460940e4d8
commit
57a7e10e74
39 changed files with 645 additions and 283 deletions
|
@ -1,4 +1,4 @@
|
|||
FROM golang:1.14-alpine as build
|
||||
FROM golang:1.15-alpine as build
|
||||
|
||||
# Create appuser and group.
|
||||
ARG USER=inetmock
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
_ "github.com/baez90/inetmock/plugins/dns_mock"
|
||||
_ "github.com/baez90/inetmock/plugins/http_mock"
|
||||
_ "github.com/baez90/inetmock/plugins/http_proxy"
|
||||
_ "github.com/baez90/inetmock/plugins/metrics_exporter"
|
||||
_ "github.com/baez90/inetmock/plugins/tls_interceptor"
|
||||
)
|
||||
|
||||
|
|
|
@ -86,3 +86,10 @@ endpoints:
|
|||
target:
|
||||
ipAddress: 127.0.0.1
|
||||
port: 53
|
||||
metrics:
|
||||
handler: metrics_exporter
|
||||
listenAddress: 0.0.0.0
|
||||
ports:
|
||||
- 9110
|
||||
options:
|
||||
route: /metrics
|
32
go.mod
32
go.mod
|
@ -1,36 +1,20 @@
|
|||
module github.com/baez90/inetmock
|
||||
|
||||
go 1.14
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/elazarl/goproxy v0.0.0-20200426045556-49ad98f6dac1 // indirect
|
||||
github.com/elazarl/goproxy/ext v0.0.0-20200426045556-49ad98f6dac1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/golang/mock v1.4.3
|
||||
github.com/golang/mock v1.4.4
|
||||
github.com/golang/protobuf v1.4.2
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/miekg/dns v1.0.14
|
||||
github.com/mitchellh/mapstructure v1.3.2 // indirect
|
||||
github.com/miekg/dns v1.1.31
|
||||
github.com/olekukonko/tablewriter v0.0.4
|
||||
github.com/pelletier/go-toml v1.8.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/spf13/afero v1.2.2 // indirect
|
||||
github.com/spf13/cast v1.3.1 // indirect
|
||||
github.com/prometheus/client_golang v1.7.1
|
||||
github.com/spf13/cobra v1.0.0
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/spf13/viper v1.7.0
|
||||
go.uber.org/zap v1.15.0
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
|
||||
golang.org/x/mod v0.3.0 // indirect
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 // indirect
|
||||
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 // indirect
|
||||
golang.org/x/tools v0.0.0-20200624060801-dcbf2a9ed15d // indirect
|
||||
google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482 // indirect
|
||||
github.com/spf13/viper v1.7.1
|
||||
go.uber.org/zap v1.16.0
|
||||
google.golang.org/grpc v1.29.1
|
||||
google.golang.org/protobuf v1.24.0
|
||||
google.golang.org/protobuf v1.23.0
|
||||
gopkg.in/elazarl/goproxy.v1 v1.0.0-20180725130230-947c36da3153
|
||||
gopkg.in/ini.v1 v1.57.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.3.0
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
|
||||
)
|
||||
|
|
138
go.sum
138
go.sum
|
@ -16,17 +16,25 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
|||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
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/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/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
|
@ -42,22 +50,23 @@ 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/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/elazarl/goproxy v0.0.0-20200426045556-49ad98f6dac1 h1:TEmChtx8+IeOghiySC8kQIr0JZOdKUmRmmkuRDuYs3E=
|
||||
github.com/elazarl/goproxy v0.0.0-20200426045556-49ad98f6dac1/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
|
||||
github.com/elazarl/goproxy v0.0.0-20200809112317-0581fc3aee2d h1:rtM8HsT3NG37YPjz8sYSbUSdElP9lUsQENYzJDZDUBE=
|
||||
github.com/elazarl/goproxy v0.0.0-20200809112317-0581fc3aee2d/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
|
||||
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
|
||||
github.com/elazarl/goproxy/ext v0.0.0-20200426045556-49ad98f6dac1 h1:nCR2gi9ueTfwN7mmtDbWEFPF+I+mW3PAJFiqlwfaJHE=
|
||||
github.com/elazarl/goproxy/ext v0.0.0-20200426045556-49ad98f6dac1/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
|
||||
github.com/elazarl/goproxy/ext v0.0.0-20200809112317-0581fc3aee2d h1:st1tmvy+4duoRj+RaeeJoECWCWM015fBtf/4aR+hhqk=
|
||||
github.com/elazarl/goproxy/ext v0.0.0-20200809112317-0581fc3aee2d/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
|
||||
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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/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-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-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
|
@ -70,6 +79,8 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
|
|||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
|
@ -79,7 +90,6 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x
|
|||
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 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
|
@ -89,6 +99,7 @@ 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/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=
|
||||
|
@ -129,6 +140,7 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH
|
|||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/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=
|
||||
|
@ -136,6 +148,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
|
|||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/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 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
|
@ -145,14 +158,20 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/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.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY=
|
||||
github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo=
|
||||
github.com/miekg/dns v1.1.31/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=
|
||||
|
@ -160,35 +179,54 @@ github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eI
|
|||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
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 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
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 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
|
||||
github.com/mitchellh/mapstructure v1.3.3/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/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
|
||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
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 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
|
||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8=
|
||||
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.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
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 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM=
|
||||
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.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY=
|
||||
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.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
|
||||
|
@ -198,20 +236,24 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb
|
|||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/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 v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/afero v1.4.0 h1:jsLTaI1zwYO3vjrzHalkVcIHXTNmdQFepW4OI8H3+x8=
|
||||
github.com/spf13/afero v1.4.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
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 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/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
|
@ -221,6 +263,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
|
|||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
|
@ -233,30 +277,38 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1
|
|||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
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.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM=
|
||||
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
|
||||
go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
|
||||
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=
|
||||
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 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002094018-c90954cbb977 h1:yH6opeNE+0SY+7pXT4gclZUoKHogXeC2EvOSHGOMGPU=
|
||||
golang.org/x/crypto v0.0.0-20201002094018-c90954cbb977/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=
|
||||
|
@ -276,10 +328,7 @@ golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU
|
|||
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.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
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-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -294,10 +343,13 @@ golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||
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 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/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-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-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10 h1:YfxMZzv3PjGonQYNUaeU2+DhAdqOxerQ30JFB6WgAXo=
|
||||
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
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=
|
||||
|
@ -305,6 +357,7 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
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 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
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=
|
||||
|
@ -317,19 +370,27 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 h1:5/PjkGUjvEU5Gl6BxmvKRPpqo2uNMv4rcHBMwzk/st8=
|
||||
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
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/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@ -351,10 +412,9 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn
|
|||
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-20191112195655-aa38f8e97acc h1:NCy3Ohtk6Iny5V/reW2Ktypo4zIpWBdRJ1uFMjBxdg8=
|
||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/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-20200624060801-dcbf2a9ed15d h1:Y4+kqqCbf46GCNf04uMqIlDYf1FuyTqSLDGywuWdRUI=
|
||||
golang.org/x/tools v0.0.0-20200624060801-dcbf2a9ed15d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/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=
|
||||
|
@ -376,17 +436,14 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn
|
|||
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-20191108220845-16a3f7862a1a h1:Ob5/580gVHBJZgXnff1cZDbG+xLtMVE5mDRTe+nIsX4=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482 h1:i+Aiej6cta/Frzp13/swvwz5O00kYcSe0A/C5Wd7zX8=
|
||||
google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
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.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
|
@ -394,28 +451,33 @@ google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ
|
|||
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 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||
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 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/elazarl/goproxy.v1 v1.0.0-20180725130230-947c36da3153 h1:i2sumy6EgvN2dbX7HPhoDc7hLyoym3OYdU5HlvUUrpE=
|
||||
gopkg.in/elazarl/goproxy.v1 v1.0.0-20180725130230-947c36da3153/go.mod h1:xzjpkyedLMz3EXUTBbkRuuGPsxfsBX3Sy7J6kC9Gvoc=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
|
||||
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.61.0 h1:LBCdW4FmFYL4s/vDZD1RQYX7oAR6IjujCYgMdbHBR10=
|
||||
gopkg.in/ini.v1 v1.61.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
|
||||
gopkg.in/yaml.v2 v2.2.5/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-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
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=
|
||||
|
|
7
internal/endpoints/constants.go
Normal file
7
internal/endpoints/constants.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package endpoints
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
shutdownTimeout = 5 * time.Second
|
||||
)
|
|
@ -1,7 +1,8 @@
|
|||
//go:generate mockgen -source=endpoint.go -destination=./../../internal/mock/endpoints/endpoint.mock.go -package=endpoints_mock
|
||||
//go:generate mockgen -source=$GOFILE -destination=./../../internal/mock/endpoints/endpoint.mock.go -package=endpoints_mock
|
||||
package endpoints
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/baez90/inetmock/pkg/api"
|
||||
"github.com/baez90/inetmock/pkg/config"
|
||||
"github.com/google/uuid"
|
||||
|
@ -10,7 +11,7 @@ import (
|
|||
type Endpoint interface {
|
||||
Id() uuid.UUID
|
||||
Start() error
|
||||
Shutdown() error
|
||||
Shutdown(ctx context.Context) error
|
||||
Name() string
|
||||
Handler() string
|
||||
Listen() string
|
||||
|
@ -48,6 +49,6 @@ func (e *endpoint) Start() (err error) {
|
|||
return e.handler.Start(e.config)
|
||||
}
|
||||
|
||||
func (e *endpoint) Shutdown() (err error) {
|
||||
return e.handler.Shutdown()
|
||||
func (e *endpoint) Shutdown(ctx context.Context) (err error) {
|
||||
return e.handler.Shutdown(ctx)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package endpoints
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/baez90/inetmock/pkg/api"
|
||||
"github.com/baez90/inetmock/pkg/config"
|
||||
|
@ -98,30 +99,36 @@ func (e *endpointManager) ShutdownEndpoints() {
|
|||
var waitGroup sync.WaitGroup
|
||||
waitGroup.Add(len(e.properlyStartedEndpoints))
|
||||
|
||||
parentCtx, _ := context.WithTimeout(context.Background(), shutdownTimeout)
|
||||
|
||||
perHandlerTimeout := e.shutdownTimePerEndpoint()
|
||||
|
||||
for _, endpoint := range e.properlyStartedEndpoints {
|
||||
ctx, _ := context.WithTimeout(parentCtx, perHandlerTimeout)
|
||||
endpointLogger := e.logger.With(
|
||||
zap.String("endpoint", endpoint.Name()),
|
||||
)
|
||||
endpointLogger.Info("Triggering shutdown of endpoint")
|
||||
go shutdownEndpoint(endpoint, endpointLogger, &waitGroup)
|
||||
go shutdownEndpoint(ctx, endpoint, endpointLogger, &waitGroup)
|
||||
}
|
||||
|
||||
waitGroup.Wait()
|
||||
}
|
||||
|
||||
func startEndpoint(ep Endpoint, logger logging.Logger) (success bool) {
|
||||
startSuccessful := make(chan bool)
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
logger.Fatal(
|
||||
"recovered panic during startup of endpoint",
|
||||
zap.Any("recovered", r),
|
||||
)
|
||||
startSuccessful <- false
|
||||
}
|
||||
}()
|
||||
|
||||
startSuccessful := make(chan bool)
|
||||
|
||||
go func() {
|
||||
if err := ep.Start(); err != nil {
|
||||
logger.Error(
|
||||
"failed to start endpoint",
|
||||
|
@ -142,7 +149,7 @@ func startEndpoint(ep Endpoint, logger logging.Logger) (success bool) {
|
|||
return
|
||||
}
|
||||
|
||||
func shutdownEndpoint(ep Endpoint, logger logging.Logger, wg *sync.WaitGroup) {
|
||||
func shutdownEndpoint(ctx context.Context, ep Endpoint, logger logging.Logger, wg *sync.WaitGroup) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
logger.Fatal(
|
||||
|
@ -152,7 +159,7 @@ func shutdownEndpoint(ep Endpoint, logger logging.Logger, wg *sync.WaitGroup) {
|
|||
}
|
||||
wg.Done()
|
||||
}()
|
||||
if err := ep.Shutdown(); err != nil {
|
||||
if err := ep.Shutdown(ctx); err != nil {
|
||||
logger.Error(
|
||||
"Failed to shutdown endpoint",
|
||||
zap.Error(err),
|
||||
|
@ -160,6 +167,10 @@ func shutdownEndpoint(ep Endpoint, logger logging.Logger, wg *sync.WaitGroup) {
|
|||
}
|
||||
}
|
||||
|
||||
func (e *endpointManager) shutdownTimePerEndpoint() time.Duration {
|
||||
return time.Duration((float64(shutdownTimeout) * 0.9) / float64(len(e.properlyStartedEndpoints)))
|
||||
}
|
||||
|
||||
func endpointComponentName(ep Endpoint) string {
|
||||
return fmt.Sprintf("endpoint_%s", ep.Name())
|
||||
}
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
package endpoints
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
api_mock "github.com/baez90/inetmock/internal/mock/api"
|
||||
apimock "github.com/baez90/inetmock/internal/mock/api"
|
||||
"github.com/baez90/inetmock/pkg/api"
|
||||
"github.com/baez90/inetmock/pkg/config"
|
||||
"github.com/golang/mock/gomock"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var (
|
||||
anyContext = context.Background()
|
||||
)
|
||||
|
||||
func Test_endpoint_Name(t *testing.T) {
|
||||
type fields struct {
|
||||
name string
|
||||
|
@ -62,9 +68,9 @@ func Test_endpoint_Shutdown(t *testing.T) {
|
|||
name: "Expect no error if mocked handler does not return one",
|
||||
fields: fields{
|
||||
handler: func() api.ProtocolHandler {
|
||||
handler := api_mock.NewMockProtocolHandler(gomock.NewController(t))
|
||||
handler := apimock.NewMockProtocolHandler(gomock.NewController(t))
|
||||
handler.EXPECT().
|
||||
Shutdown().
|
||||
Shutdown(gomock.Any()).
|
||||
MaxTimes(1).
|
||||
Return(nil)
|
||||
return handler
|
||||
|
@ -76,9 +82,9 @@ func Test_endpoint_Shutdown(t *testing.T) {
|
|||
name: "Expect error if mocked handler returns one",
|
||||
fields: fields{
|
||||
handler: func() api.ProtocolHandler {
|
||||
handler := api_mock.NewMockProtocolHandler(gomock.NewController(t))
|
||||
handler := apimock.NewMockProtocolHandler(gomock.NewController(t))
|
||||
handler.EXPECT().
|
||||
Shutdown().
|
||||
Shutdown(gomock.AssignableToTypeOf(reflect.TypeOf(context.Background()))).
|
||||
MaxTimes(1).
|
||||
Return(fmt.Errorf(""))
|
||||
return handler
|
||||
|
@ -94,7 +100,7 @@ func Test_endpoint_Shutdown(t *testing.T) {
|
|||
handler: tt.fields.handler,
|
||||
config: tt.fields.config,
|
||||
}
|
||||
if err := e.Shutdown(); (err != nil) != tt.wantErr {
|
||||
if err := e.Shutdown(context.Background()); (err != nil) != tt.wantErr {
|
||||
t.Errorf("Shutdown() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
|
@ -123,7 +129,7 @@ func Test_endpoint_Start(t *testing.T) {
|
|||
name: "Expect no error if mocked handler does not return one",
|
||||
fields: fields{
|
||||
handler: func() api.ProtocolHandler {
|
||||
handler := api_mock.NewMockProtocolHandler(gomock.NewController(t))
|
||||
handler := apimock.NewMockProtocolHandler(gomock.NewController(t))
|
||||
handler.EXPECT().
|
||||
Start(gomock.Any()).
|
||||
MaxTimes(1).
|
||||
|
@ -137,7 +143,7 @@ func Test_endpoint_Start(t *testing.T) {
|
|||
name: "Expect error if mocked handler returns one",
|
||||
fields: fields{
|
||||
handler: func() api.ProtocolHandler {
|
||||
handler := api_mock.NewMockProtocolHandler(gomock.NewController(t))
|
||||
handler := apimock.NewMockProtocolHandler(gomock.NewController(t))
|
||||
handler.EXPECT().
|
||||
Start(gomock.Any()).
|
||||
MaxTimes(1).
|
||||
|
@ -152,7 +158,7 @@ func Test_endpoint_Start(t *testing.T) {
|
|||
fields: fields{
|
||||
config: demoHandlerConfig,
|
||||
handler: func() api.ProtocolHandler {
|
||||
handler := api_mock.NewMockProtocolHandler(gomock.NewController(t))
|
||||
handler := apimock.NewMockProtocolHandler(gomock.NewController(t))
|
||||
handler.EXPECT().
|
||||
Start(demoHandlerConfig).
|
||||
MaxTimes(1).
|
||||
|
|
|
@ -3,7 +3,7 @@ package format
|
|||
import (
|
||||
"encoding/json"
|
||||
"github.com/olekukonko/tablewriter"
|
||||
"gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package format
|
||||
|
||||
import (
|
||||
"gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type yamlWriter struct {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
//go:generate mockgen -source=protocol_handler.go -destination=./../../internal/mock/api/protocol_handler.mock.go -package=api_mock
|
||||
//go:generate mockgen -source=$GOFILE -destination=./../../internal/mock/api/protocol_handler.mock.go -package=api_mock
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/baez90/inetmock/pkg/config"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
@ -12,5 +13,5 @@ type LoggingFactory func() (*zap.Logger, error)
|
|||
|
||||
type ProtocolHandler interface {
|
||||
Start(config config.HandlerConfig) error
|
||||
Shutdown() error
|
||||
Shutdown(ctx context.Context) error
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//go:generate mockgen -source=registration.go -destination=./../../internal/mock/plugins/handler_registry.mock.go -package=plugins_mock
|
||||
//go:generate mockgen -source=$GOFILE -destination=./../../internal/mock/plugins/handler_registry.mock.go -package=plugins_mock
|
||||
package api
|
||||
|
||||
import (
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//go:generate mockgen -source=cache.go -destination=./../../internal/mock/cert/cert_cache.mock.go -package=cert_mock
|
||||
//go:generate mockgen -source=$GOFILE -destination=./../../internal/mock/cert/cert_cache.mock.go -package=cert_mock
|
||||
|
||||
package cert
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//go:generate mockgen -source=time_source.go -destination=./../../internal/mock/cert/time_source.mock.go -package=cert_mock
|
||||
//go:generate mockgen -source=$GOFILE -destination=./../../internal/mock/cert/time_source.mock.go -package=cert_mock
|
||||
|
||||
package cert
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package config
|
||||
|
||||
import "github.com/spf13/viper"
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type HandlerConfig struct {
|
||||
HandlerName string
|
||||
|
@ -8,3 +11,7 @@ type HandlerConfig struct {
|
|||
ListenAddress string
|
||||
Options *viper.Viper
|
||||
}
|
||||
|
||||
func (h HandlerConfig) ListenAddr() string {
|
||||
return fmt.Sprintf("%s:%d", h.ListenAddress, h.Port)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//go:generate mockgen -source=logger.go -destination=./../../internal/mock/logging/logger.mock.go -package=logging_mock
|
||||
//go:generate mockgen -source=$GOFILE -destination=./../../internal/mock/logging/logger.mock.go -package=logging_mock
|
||||
package logging
|
||||
|
||||
import "go.uber.org/zap"
|
||||
|
|
47
pkg/metrics/metrics_factory.go
Normal file
47
pkg/metrics/metrics_factory.go
Normal file
|
@ -0,0 +1,47 @@
|
|||
package metrics
|
||||
|
||||
import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
metricNamespace = "inetmock"
|
||||
)
|
||||
|
||||
func Gauge(subsystem, name, help string, labelNames ...string) (*prometheus.GaugeVec, error) {
|
||||
vec := prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Namespace: metricNamespace,
|
||||
Subsystem: subsystem,
|
||||
Name: name,
|
||||
Help: help,
|
||||
}, labelNames)
|
||||
return vec, prometheus.Register(vec)
|
||||
}
|
||||
|
||||
func Histogram(subsystem, name, help string, buckets []float64, labelNames ...string) (*prometheus.HistogramVec, error) {
|
||||
vec := prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Namespace: metricNamespace,
|
||||
Subsystem: subsystem,
|
||||
Name: name,
|
||||
Help: help,
|
||||
Buckets: buckets,
|
||||
},
|
||||
labelNames,
|
||||
)
|
||||
return vec, prometheus.Register(vec)
|
||||
}
|
||||
|
||||
func Counter(subsystem, name, help string, labelNames ...string) (*prometheus.CounterVec, error) {
|
||||
vec := prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Namespace: metricNamespace,
|
||||
Subsystem: subsystem,
|
||||
Name: name,
|
||||
Help: help,
|
||||
},
|
||||
labelNames,
|
||||
)
|
||||
return vec, prometheus.Register(vec)
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package dns_mock
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"context"
|
||||
"github.com/baez90/inetmock/pkg/config"
|
||||
"github.com/baez90/inetmock/pkg/logging"
|
||||
"github.com/miekg/dns"
|
||||
|
@ -14,10 +14,19 @@ type dnsHandler struct {
|
|||
}
|
||||
|
||||
func (d *dnsHandler) Start(config config.HandlerConfig) (err error) {
|
||||
options := loadFromConfig(config.Options)
|
||||
addr := fmt.Sprintf("%s:%d", config.ListenAddress, config.Port)
|
||||
var options dnsOptions
|
||||
if options, err = loadFromConfig(config.Options); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
listenAddr := config.ListenAddr()
|
||||
d.logger = d.logger.With(
|
||||
zap.String("handler_name", config.HandlerName),
|
||||
zap.String("address", listenAddr),
|
||||
)
|
||||
|
||||
handler := ®exHandler{
|
||||
handlerName: config.HandlerName,
|
||||
fallback: options.Fallback,
|
||||
logger: d.logger,
|
||||
}
|
||||
|
@ -32,17 +41,17 @@ func (d *dnsHandler) Start(config config.HandlerConfig) (err error) {
|
|||
}
|
||||
|
||||
d.logger = d.logger.With(
|
||||
zap.String("address", addr),
|
||||
zap.String("address", listenAddr),
|
||||
)
|
||||
|
||||
d.dnsServer = []*dns.Server{
|
||||
{
|
||||
Addr: addr,
|
||||
Addr: listenAddr,
|
||||
Net: "udp",
|
||||
Handler: handler,
|
||||
},
|
||||
{
|
||||
Addr: addr,
|
||||
Addr: listenAddr,
|
||||
Net: "tcp",
|
||||
Handler: handler,
|
||||
},
|
||||
|
@ -63,10 +72,10 @@ func (d *dnsHandler) startServer(dnsServer *dns.Server) {
|
|||
}
|
||||
}
|
||||
|
||||
func (d *dnsHandler) Shutdown() error {
|
||||
func (d *dnsHandler) Shutdown(ctx context.Context) error {
|
||||
d.logger.Info("shutting down DNS mock")
|
||||
for _, dnsServer := range d.dnsServer {
|
||||
if err := dnsServer.Shutdown(); err != nil {
|
||||
if err := dnsServer.ShutdownContext(ctx); err != nil {
|
||||
d.logger.Error(
|
||||
"failed to shutdown server",
|
||||
zap.Error(err),
|
||||
|
|
|
@ -3,6 +3,8 @@ package dns_mock
|
|||
import (
|
||||
"github.com/baez90/inetmock/pkg/api"
|
||||
"github.com/baez90/inetmock/pkg/logging"
|
||||
"github.com/baez90/inetmock/pkg/metrics"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
@ -10,12 +12,51 @@ const (
|
|||
name = "dns_mock"
|
||||
)
|
||||
|
||||
var (
|
||||
handlerNameLblName = "handler_name"
|
||||
totalHandledRequestsCounter *prometheus.CounterVec
|
||||
unhandledRequestsCounter *prometheus.CounterVec
|
||||
requestDurationHistogram *prometheus.HistogramVec
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger, _ := logging.CreateLogger()
|
||||
var err error
|
||||
var logger logging.Logger
|
||||
if logger, err = logging.CreateLogger(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
logger = logger.With(
|
||||
zap.String("ProtocolHandler", name),
|
||||
zap.String("protocol_handler", name),
|
||||
)
|
||||
|
||||
if totalHandledRequestsCounter, err = metrics.Counter(
|
||||
name,
|
||||
"handled_requests_total",
|
||||
"",
|
||||
handlerNameLblName,
|
||||
); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if unhandledRequestsCounter, err = metrics.Counter(
|
||||
name,
|
||||
"unhandled_requests_total",
|
||||
"",
|
||||
handlerNameLblName,
|
||||
); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if requestDurationHistogram, err = metrics.Histogram(
|
||||
name,
|
||||
"request_duration",
|
||||
"",
|
||||
nil,
|
||||
handlerNameLblName,
|
||||
); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
api.Registry().RegisterHandler(name, func() api.ProtocolHandler {
|
||||
return &dnsHandler{
|
||||
logger: logger,
|
||||
|
|
|
@ -7,10 +7,6 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
rulesConfigKey = "rules"
|
||||
patternConfigKey = "pattern"
|
||||
responseConfigKey = "response"
|
||||
fallbackStrategyConfigKey = "fallback.strategy"
|
||||
fallbackArgsConfigKey = "fallback.args"
|
||||
)
|
||||
|
||||
|
@ -24,33 +20,40 @@ type dnsOptions struct {
|
|||
Fallback ResolverFallback
|
||||
}
|
||||
|
||||
func loadFromConfig(config *viper.Viper) dnsOptions {
|
||||
options := dnsOptions{}
|
||||
func loadFromConfig(config *viper.Viper) (options dnsOptions, err error) {
|
||||
type rule struct {
|
||||
Pattern string
|
||||
Response string
|
||||
}
|
||||
|
||||
anonRules := config.Get(rulesConfigKey).([]interface{})
|
||||
for _, rule := range anonRules {
|
||||
innerData := rule.(map[interface{}]interface{})
|
||||
type fallback struct {
|
||||
Strategy string
|
||||
}
|
||||
|
||||
opts := struct {
|
||||
Rules []rule
|
||||
Fallback fallback
|
||||
}{}
|
||||
|
||||
err = config.Unmarshal(&opts)
|
||||
|
||||
for _, rule := range opts.Rules {
|
||||
var err error
|
||||
var compiledPattern *regexp.Regexp
|
||||
var response net.IP
|
||||
if compiledPattern, err = regexp.Compile(innerData[patternConfigKey].(string)); err != nil {
|
||||
var rr resolverRule
|
||||
if rr.pattern, err = regexp.Compile(rule.Pattern); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if response = net.ParseIP(innerData[responseConfigKey].(string)); response == nil {
|
||||
if rr.response = net.ParseIP(rule.Response); rr.response == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
options.Rules = append(options.Rules, resolverRule{
|
||||
pattern: compiledPattern,
|
||||
response: response,
|
||||
})
|
||||
options.Rules = append(options.Rules, rr)
|
||||
}
|
||||
|
||||
options.Fallback = CreateResolverFallback(
|
||||
config.GetString(fallbackStrategyConfigKey),
|
||||
opts.Fallback.Strategy,
|
||||
config.Sub(fallbackArgsConfigKey),
|
||||
)
|
||||
|
||||
return options
|
||||
return
|
||||
}
|
||||
|
|
|
@ -3,45 +3,53 @@ package dns_mock
|
|||
import (
|
||||
"github.com/baez90/inetmock/pkg/logging"
|
||||
"github.com/miekg/dns"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type regexHandler struct {
|
||||
handlerName string
|
||||
routes []resolverRule
|
||||
fallback ResolverFallback
|
||||
logger logging.Logger
|
||||
}
|
||||
|
||||
func (r2 *regexHandler) AddRule(rule resolverRule) {
|
||||
r2.routes = append(r2.routes, rule)
|
||||
func (rh *regexHandler) AddRule(rule resolverRule) {
|
||||
rh.routes = append(rh.routes, rule)
|
||||
}
|
||||
|
||||
func (r2 regexHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
|
||||
func (rh regexHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
|
||||
timer := prometheus.NewTimer(requestDurationHistogram.WithLabelValues(rh.handlerName))
|
||||
defer func() {
|
||||
timer.ObserveDuration()
|
||||
}()
|
||||
|
||||
m := new(dns.Msg)
|
||||
m.Compress = false
|
||||
m.SetReply(r)
|
||||
|
||||
switch r.Opcode {
|
||||
case dns.OpcodeQuery:
|
||||
r2.handleQuery(m)
|
||||
rh.handleQuery(m)
|
||||
}
|
||||
if err := w.WriteMsg(m); err != nil {
|
||||
r2.logger.Error(
|
||||
rh.logger.Error(
|
||||
"Failed to write DNS response message",
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func (r2 regexHandler) handleQuery(m *dns.Msg) {
|
||||
func (rh regexHandler) handleQuery(m *dns.Msg) {
|
||||
for _, q := range m.Question {
|
||||
r2.logger.Info(
|
||||
rh.logger.Info(
|
||||
"handling question",
|
||||
zap.String("question", q.Name),
|
||||
)
|
||||
switch q.Qtype {
|
||||
case dns.TypeA:
|
||||
for _, rule := range r2.routes {
|
||||
totalHandledRequestsCounter.WithLabelValues(rh.handlerName).Inc()
|
||||
for _, rule := range rh.routes {
|
||||
if rule.pattern.MatchString(q.Name) {
|
||||
m.Authoritative = true
|
||||
answer := &dns.A{
|
||||
|
@ -54,7 +62,7 @@ func (r2 regexHandler) handleQuery(m *dns.Msg) {
|
|||
A: rule.response,
|
||||
}
|
||||
m.Answer = append(m.Answer, answer)
|
||||
r2.logger.Info(
|
||||
rh.logger.Info(
|
||||
"matched DNS rule",
|
||||
zap.String("pattern", rule.pattern.String()),
|
||||
zap.String("response", rule.response.String()),
|
||||
|
@ -62,13 +70,19 @@ func (r2 regexHandler) handleQuery(m *dns.Msg) {
|
|||
return
|
||||
}
|
||||
}
|
||||
r2.handleFallbackForMessage(m, q)
|
||||
rh.handleFallbackForMessage(m, q)
|
||||
default:
|
||||
unhandledRequestsCounter.WithLabelValues(rh.handlerName).Inc()
|
||||
rh.logger.Warn(
|
||||
"Unhandled DNS question type - no response will be sent",
|
||||
zap.Uint16("question_type", q.Qtype),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r2 regexHandler) handleFallbackForMessage(m *dns.Msg, q dns.Question) {
|
||||
fallbackIP := r2.fallback.GetIP()
|
||||
func (rh regexHandler) handleFallbackForMessage(m *dns.Msg, q dns.Question) {
|
||||
fallbackIP := rh.fallback.GetIP()
|
||||
answer := &dns.A{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: q.Name,
|
||||
|
@ -78,7 +92,7 @@ func (r2 regexHandler) handleFallbackForMessage(m *dns.Msg, q dns.Question) {
|
|||
},
|
||||
A: fallbackIP,
|
||||
}
|
||||
r2.logger.Info(
|
||||
rh.logger.Info(
|
||||
"Falling back to generated IP",
|
||||
zap.String("response", fallbackIP.String()),
|
||||
)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package http_mock
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/baez90/inetmock/pkg/config"
|
||||
"github.com/baez90/inetmock/pkg/logging"
|
||||
|
@ -10,33 +12,39 @@ import (
|
|||
|
||||
const (
|
||||
name = "http_mock"
|
||||
handlerNameLblName = "handler_name"
|
||||
ruleMatchedLblName = "rule_matched"
|
||||
)
|
||||
|
||||
type httpHandler struct {
|
||||
logger logging.Logger
|
||||
router *RegexpHandler
|
||||
server *http.Server
|
||||
}
|
||||
|
||||
func (p *httpHandler) Start(config config.HandlerConfig) (err error) {
|
||||
options := loadFromConfig(config.Options)
|
||||
addr := fmt.Sprintf("%s:%d", config.ListenAddress, config.Port)
|
||||
p.server = &http.Server{Addr: addr, Handler: p.router}
|
||||
p.logger = p.logger.With(
|
||||
zap.String("address", addr),
|
||||
zap.String("handler_name", config.HandlerName),
|
||||
zap.String("address", config.ListenAddr()),
|
||||
)
|
||||
|
||||
router := &RegexpHandler{
|
||||
logger: p.logger,
|
||||
handlerName: config.HandlerName,
|
||||
}
|
||||
p.server = &http.Server{Addr: config.ListenAddr(), Handler: router}
|
||||
|
||||
for _, rule := range options.Rules {
|
||||
p.setupRoute(rule)
|
||||
router.setupRoute(rule)
|
||||
}
|
||||
|
||||
go p.startServer()
|
||||
return
|
||||
}
|
||||
|
||||
func (p *httpHandler) Shutdown() (err error) {
|
||||
func (p *httpHandler) Shutdown(ctx context.Context) (err error) {
|
||||
p.logger.Info("Shutting down HTTP mock")
|
||||
if err = p.server.Close(); err != nil {
|
||||
if err = p.server.Shutdown(ctx); err != nil {
|
||||
p.logger.Error(
|
||||
"failed to shutdown HTTP server",
|
||||
zap.Error(err),
|
||||
|
@ -50,7 +58,7 @@ func (p *httpHandler) Shutdown() (err error) {
|
|||
}
|
||||
|
||||
func (p *httpHandler) startServer() {
|
||||
if err := p.server.ListenAndServe(); err != nil {
|
||||
if err := p.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
p.logger.Error(
|
||||
"failed to start http listener",
|
||||
zap.Error(err),
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
package http_mock
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/baez90/inetmock/pkg/logging"
|
||||
"go.uber.org/zap"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (p *httpHandler) setupRoute(rule targetRule) {
|
||||
p.logger.Info(
|
||||
"setup routing",
|
||||
zap.String("route", rule.Pattern().String()),
|
||||
zap.String("response", rule.Response()),
|
||||
)
|
||||
|
||||
p.router.Handler(rule.Pattern(), createHandlerForTarget(p.logger, rule.response))
|
||||
}
|
||||
|
||||
func createHandlerForTarget(logger logging.Logger, targetPath string) http.Handler {
|
||||
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
||||
headerWriter := &bytes.Buffer{}
|
||||
request.Header.Write(headerWriter)
|
||||
|
||||
logger.Info(
|
||||
"Handling request",
|
||||
zap.String("source", request.RemoteAddr),
|
||||
zap.String("host", request.Host),
|
||||
zap.String("method", request.Method),
|
||||
zap.String("protocol", request.Proto),
|
||||
zap.String("path", request.RequestURI),
|
||||
zap.String("response", targetPath),
|
||||
zap.Reflect("headers", request.Header),
|
||||
)
|
||||
|
||||
http.ServeFile(writer, request, targetPath)
|
||||
})
|
||||
}
|
|
@ -3,18 +3,46 @@ package http_mock
|
|||
import (
|
||||
"github.com/baez90/inetmock/pkg/api"
|
||||
"github.com/baez90/inetmock/pkg/logging"
|
||||
"github.com/baez90/inetmock/pkg/metrics"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var (
|
||||
totalRequestCounter *prometheus.CounterVec
|
||||
requestDurationHistogram *prometheus.HistogramVec
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger, _ := logging.CreateLogger()
|
||||
var err error
|
||||
var logger logging.Logger
|
||||
if logger, err = logging.CreateLogger(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
logger = logger.With(
|
||||
zap.String("ProtocolHandler", name),
|
||||
zap.String("protocol_handler", name),
|
||||
)
|
||||
if totalRequestCounter, err = metrics.Counter(
|
||||
name,
|
||||
"total_requests",
|
||||
"",
|
||||
handlerNameLblName,
|
||||
ruleMatchedLblName,
|
||||
); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if requestDurationHistogram, err = metrics.Histogram(
|
||||
name,
|
||||
"request_duration",
|
||||
"",
|
||||
nil,
|
||||
handlerNameLblName,
|
||||
); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
api.Registry().RegisterHandler(name, func() api.ProtocolHandler {
|
||||
return &httpHandler{
|
||||
logger: logger,
|
||||
router: &RegexpHandler{},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
package http_mock
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/baez90/inetmock/pkg/logging"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"go.uber.org/zap"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type route struct {
|
||||
|
@ -11,6 +16,8 @@ type route struct {
|
|||
}
|
||||
|
||||
type RegexpHandler struct {
|
||||
handlerName string
|
||||
logger logging.Logger
|
||||
routes []*route
|
||||
}
|
||||
|
||||
|
@ -23,12 +30,47 @@ func (h *RegexpHandler) HandleFunc(pattern *regexp.Regexp, handler func(http.Res
|
|||
}
|
||||
|
||||
func (h *RegexpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
timer := prometheus.NewTimer(requestDurationHistogram.WithLabelValues(h.handlerName))
|
||||
defer timer.ObserveDuration()
|
||||
|
||||
for _, route := range h.routes {
|
||||
if route.pattern.MatchString(r.URL.Path) {
|
||||
totalRequestCounter.WithLabelValues(h.handlerName, strconv.FormatBool(true)).Inc()
|
||||
route.handler.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
// no pattern matched; send 404 response
|
||||
totalRequestCounter.WithLabelValues(h.handlerName, strconv.FormatBool(false)).Inc()
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
||||
func (h *RegexpHandler) setupRoute(rule targetRule) {
|
||||
h.logger.Info(
|
||||
"setup routing",
|
||||
zap.String("route", rule.Pattern().String()),
|
||||
zap.String("response", rule.Response()),
|
||||
)
|
||||
|
||||
h.Handler(rule.Pattern(), createHandlerForTarget(h.logger, rule.response))
|
||||
}
|
||||
|
||||
func createHandlerForTarget(logger logging.Logger, targetPath string) http.Handler {
|
||||
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
||||
headerWriter := &bytes.Buffer{}
|
||||
request.Header.Write(headerWriter)
|
||||
|
||||
logger.Info(
|
||||
"Handling request",
|
||||
zap.String("source", request.RemoteAddr),
|
||||
zap.String("host", request.Host),
|
||||
zap.String("method", request.Method),
|
||||
zap.String("protocol", request.Proto),
|
||||
zap.String("path", request.RequestURI),
|
||||
zap.String("response", targetPath),
|
||||
zap.Reflect("headers", request.Header),
|
||||
)
|
||||
|
||||
http.ServeFile(writer, request, targetPath)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package http_proxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/baez90/inetmock/pkg/api"
|
||||
"github.com/baez90/inetmock/pkg/config"
|
||||
|
@ -21,21 +23,27 @@ type httpProxy struct {
|
|||
}
|
||||
|
||||
func (h *httpProxy) Start(config config.HandlerConfig) (err error) {
|
||||
options := loadFromConfig(config.Options)
|
||||
addr := fmt.Sprintf("%s:%d", config.ListenAddress, config.Port)
|
||||
h.server = &http.Server{Addr: addr, Handler: h.proxy}
|
||||
var opts httpProxyOptions
|
||||
if err = config.Options.Unmarshal(&opts); err != nil {
|
||||
return
|
||||
}
|
||||
listenAddr := config.ListenAddr()
|
||||
h.server = &http.Server{Addr: listenAddr, Handler: h.proxy}
|
||||
h.logger = h.logger.With(
|
||||
zap.String("address", addr),
|
||||
zap.String("handler_name", config.HandlerName),
|
||||
zap.String("address", listenAddr),
|
||||
)
|
||||
|
||||
tlsConfig := api.ServicesInstance().CertStore().TLSConfig()
|
||||
|
||||
proxyHandler := &proxyHttpHandler{
|
||||
options: options,
|
||||
handlerName: config.HandlerName,
|
||||
options: opts,
|
||||
logger: h.logger,
|
||||
}
|
||||
|
||||
proxyHttpsHandler := &proxyHttpsHandler{
|
||||
handlerName: config.HandlerName,
|
||||
tlsConfig: tlsConfig,
|
||||
logger: h.logger,
|
||||
}
|
||||
|
@ -47,7 +55,7 @@ func (h *httpProxy) Start(config config.HandlerConfig) (err error) {
|
|||
}
|
||||
|
||||
func (h *httpProxy) startProxy() {
|
||||
if err := h.server.ListenAndServe(); err != nil {
|
||||
if err := h.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
h.logger.Error(
|
||||
"failed to start proxy server",
|
||||
zap.Error(err),
|
||||
|
@ -55,9 +63,9 @@ func (h *httpProxy) startProxy() {
|
|||
}
|
||||
}
|
||||
|
||||
func (h *httpProxy) Shutdown() (err error) {
|
||||
func (h *httpProxy) Shutdown(ctx context.Context) (err error) {
|
||||
h.logger.Info("Shutting down HTTP proxy")
|
||||
if err = h.server.Close(); err != nil {
|
||||
if err = h.server.Shutdown(ctx); err != nil {
|
||||
h.logger.Error(
|
||||
"failed to shutdown proxy endpoint",
|
||||
zap.Error(err),
|
||||
|
|
|
@ -3,16 +3,41 @@ package http_proxy
|
|||
import (
|
||||
"github.com/baez90/inetmock/pkg/api"
|
||||
"github.com/baez90/inetmock/pkg/logging"
|
||||
"github.com/baez90/inetmock/pkg/metrics"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"go.uber.org/zap"
|
||||
"gopkg.in/elazarl/goproxy.v1"
|
||||
)
|
||||
|
||||
var (
|
||||
handlerNameLblName = "handler_name"
|
||||
totalRequestCounter *prometheus.CounterVec
|
||||
totalHttpsRequestCounter *prometheus.CounterVec
|
||||
requestDurationHistogram *prometheus.HistogramVec
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger, _ := logging.CreateLogger()
|
||||
var err error
|
||||
var logger logging.Logger
|
||||
if logger, err = logging.CreateLogger(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
logger = logger.With(
|
||||
zap.String("ProtocolHandler", name),
|
||||
zap.String("protocol_handler", name),
|
||||
)
|
||||
|
||||
if totalRequestCounter, err = metrics.Counter(name, "total_requests", "", handlerNameLblName); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if requestDurationHistogram, err = metrics.Histogram(name, "request_duration", "", nil, handlerNameLblName); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if totalHttpsRequestCounter, err = metrics.Counter(name, "total_https_requests", "", handlerNameLblName); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
api.Registry().RegisterHandler(name, func() api.ProtocolHandler {
|
||||
return &httpProxy{
|
||||
logger: logger,
|
||||
|
|
|
@ -2,41 +2,17 @@ package http_proxy
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
targetSchemeConfigKey = "target.scheme"
|
||||
targetIpAddressConfigKey = "target.ipAddress"
|
||||
targetPortConfigKey = "target.port"
|
||||
)
|
||||
|
||||
type redirectionTarget struct {
|
||||
scheme string
|
||||
ipAddress string
|
||||
port uint16
|
||||
IPAddress string
|
||||
Port uint16
|
||||
}
|
||||
|
||||
func (rt redirectionTarget) host() string {
|
||||
return fmt.Sprintf("%s:%d", rt.ipAddress, rt.port)
|
||||
return fmt.Sprintf("%s:%d", rt.IPAddress, rt.Port)
|
||||
}
|
||||
|
||||
type httpProxyOptions struct {
|
||||
redirectionTarget redirectionTarget
|
||||
}
|
||||
|
||||
func loadFromConfig(config *viper.Viper) (options httpProxyOptions) {
|
||||
|
||||
config.SetDefault(targetSchemeConfigKey, "http")
|
||||
config.SetDefault(targetIpAddressConfigKey, "127.0.0.1")
|
||||
config.SetDefault(targetPortConfigKey, "80")
|
||||
|
||||
options = httpProxyOptions{
|
||||
redirectionTarget{
|
||||
scheme: config.GetString(targetSchemeConfigKey),
|
||||
ipAddress: config.GetString(targetIpAddressConfigKey),
|
||||
port: uint16(config.GetInt(targetPortConfigKey)),
|
||||
},
|
||||
}
|
||||
return
|
||||
Target redirectionTarget
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
package http_proxy
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"crypto/tls"
|
||||
"github.com/baez90/inetmock/pkg/logging"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"go.uber.org/zap"
|
||||
"gopkg.in/elazarl/goproxy.v1"
|
||||
"net/http"
|
||||
|
@ -11,16 +12,19 @@ import (
|
|||
)
|
||||
|
||||
type proxyHttpHandler struct {
|
||||
handlerName string
|
||||
options httpProxyOptions
|
||||
logger logging.Logger
|
||||
}
|
||||
|
||||
type proxyHttpsHandler struct {
|
||||
handlerName string
|
||||
tlsConfig *tls.Config
|
||||
logger logging.Logger
|
||||
}
|
||||
|
||||
func (p *proxyHttpsHandler) HandleConnect(req string, _ *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
|
||||
totalHttpsRequestCounter.WithLabelValues(p.handlerName).Inc()
|
||||
p.logger.Info(
|
||||
"Intercepting HTTPS proxy request",
|
||||
zap.String("request", req),
|
||||
|
@ -35,6 +39,10 @@ func (p *proxyHttpsHandler) HandleConnect(req string, _ *goproxy.ProxyCtx) (*gop
|
|||
}
|
||||
|
||||
func (p *proxyHttpHandler) Handle(req *http.Request, ctx *goproxy.ProxyCtx) (retReq *http.Request, resp *http.Response) {
|
||||
timer := prometheus.NewTimer(requestDurationHistogram.WithLabelValues(p.handlerName))
|
||||
defer timer.ObserveDuration()
|
||||
totalRequestCounter.WithLabelValues(p.handlerName).Inc()
|
||||
|
||||
retReq = req
|
||||
p.logger.Info(
|
||||
"Handling request",
|
||||
|
@ -62,8 +70,7 @@ func (p proxyHttpHandler) redirectHTTPRequest(originalRequest *http.Request) (re
|
|||
redirectReq = &http.Request{
|
||||
Method: originalRequest.Method,
|
||||
URL: &url.URL{
|
||||
Host: p.options.redirectionTarget.host(),
|
||||
Scheme: p.options.redirectionTarget.scheme,
|
||||
Host: p.options.Target.host(),
|
||||
Path: originalRequest.URL.Path,
|
||||
ForceQuery: originalRequest.URL.ForceQuery,
|
||||
Fragment: originalRequest.URL.Fragment,
|
||||
|
|
53
plugins/metrics_exporter/handler.go
Normal file
53
plugins/metrics_exporter/handler.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
package metrics_exporter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/baez90/inetmock/pkg/config"
|
||||
"github.com/baez90/inetmock/pkg/logging"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"go.uber.org/zap"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
name = "metrics_exporter"
|
||||
)
|
||||
|
||||
type metricsExporter struct {
|
||||
logger logging.Logger
|
||||
server *http.Server
|
||||
}
|
||||
|
||||
func (m *metricsExporter) Start(config config.HandlerConfig) (err error) {
|
||||
exporterOptions := metricsExporterOptions{}
|
||||
if err = config.Options.Unmarshal(&exporterOptions); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
m.logger = m.logger.With(
|
||||
zap.String("handler_name", config.HandlerName),
|
||||
zap.String("address", config.ListenAddr()),
|
||||
)
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle(exporterOptions.Route, promhttp.Handler())
|
||||
m.server = &http.Server{
|
||||
Addr: config.ListenAddr(),
|
||||
Handler: mux,
|
||||
}
|
||||
|
||||
go func() {
|
||||
if err := m.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
m.logger.Error(
|
||||
"Error occurred while serving metrics",
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
}()
|
||||
return
|
||||
}
|
||||
|
||||
func (m *metricsExporter) Shutdown(ctx context.Context) error {
|
||||
return m.server.Shutdown(ctx)
|
||||
}
|
20
plugins/metrics_exporter/init.go
Normal file
20
plugins/metrics_exporter/init.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
package metrics_exporter
|
||||
|
||||
import (
|
||||
"github.com/baez90/inetmock/pkg/api"
|
||||
"github.com/baez90/inetmock/pkg/logging"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger, _ := logging.CreateLogger()
|
||||
logger = logger.With(
|
||||
zap.String("protocol_handler", name),
|
||||
)
|
||||
|
||||
api.Registry().RegisterHandler(name, func() api.ProtocolHandler {
|
||||
return &metricsExporter{
|
||||
logger: logger,
|
||||
}
|
||||
})
|
||||
}
|
5
plugins/metrics_exporter/protocol_options.go
Normal file
5
plugins/metrics_exporter/protocol_options.go
Normal file
|
@ -0,0 +1,5 @@
|
|||
package metrics_exporter
|
||||
|
||||
type metricsExporterOptions struct {
|
||||
Route string
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package tls_interceptor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"github.com/baez90/inetmock/pkg/api"
|
||||
|
@ -8,10 +9,10 @@ import (
|
|||
"github.com/baez90/inetmock/pkg/config"
|
||||
"github.com/baez90/inetmock/pkg/logging"
|
||||
"github.com/google/uuid"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"go.uber.org/zap"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -19,6 +20,7 @@ const (
|
|||
)
|
||||
|
||||
type tlsInterceptor struct {
|
||||
name string
|
||||
options tlsOptions
|
||||
logger logging.Logger
|
||||
listener net.Listener
|
||||
|
@ -30,15 +32,18 @@ type tlsInterceptor struct {
|
|||
}
|
||||
|
||||
func (t *tlsInterceptor) Start(config config.HandlerConfig) (err error) {
|
||||
t.options = loadFromConfig(config.Options)
|
||||
addr := fmt.Sprintf("%s:%d", config.ListenAddress, config.Port)
|
||||
t.name = config.HandlerName
|
||||
if err = config.Options.Unmarshal(&config.Options); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
t.logger = t.logger.With(
|
||||
zap.String("address", addr),
|
||||
zap.String("target", t.options.redirectionTarget.address()),
|
||||
zap.String("handler_name", config.HandlerName),
|
||||
zap.String("address", config.ListenAddr()),
|
||||
zap.String("Target", t.options.Target.address()),
|
||||
)
|
||||
|
||||
if t.listener, err = tls.Listen("tcp", addr, api.ServicesInstance().CertStore().TLSConfig()); err != nil {
|
||||
if t.listener, err = tls.Listen("tcp", config.ListenAddr(), api.ServicesInstance().CertStore().TLSConfig()); err != nil {
|
||||
t.logger.Fatal(
|
||||
"failed to create tls listener",
|
||||
zap.Error(err),
|
||||
|
@ -54,7 +59,7 @@ func (t *tlsInterceptor) Start(config config.HandlerConfig) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (t *tlsInterceptor) Shutdown() (err error) {
|
||||
func (t *tlsInterceptor) Shutdown(ctx context.Context) (err error) {
|
||||
t.logger.Info("Shutting down TLS interceptor")
|
||||
t.shutdownRequested = true
|
||||
done := make(chan struct{})
|
||||
|
@ -66,7 +71,7 @@ func (t *tlsInterceptor) Shutdown() (err error) {
|
|||
select {
|
||||
case <-done:
|
||||
return
|
||||
case <-time.After(5 * time.Second):
|
||||
case <-ctx.Done():
|
||||
for _, proxyConn := range t.currentConnections {
|
||||
if err = proxyConn.Close(); err != nil {
|
||||
t.logger.Error(
|
||||
|
@ -94,19 +99,26 @@ func (t *tlsInterceptor) startListener() {
|
|||
continue
|
||||
}
|
||||
|
||||
handledRequestCounter.WithLabelValues(t.name).Inc()
|
||||
openConnectionsGauge.WithLabelValues(t.name).Inc()
|
||||
t.currentConnectionsCount.Add(1)
|
||||
go t.proxyConn(conn)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tlsInterceptor) proxyConn(conn net.Conn) {
|
||||
defer conn.Close()
|
||||
defer t.currentConnectionsCount.Done()
|
||||
timer := prometheus.NewTimer(requestDurationHistogram.WithLabelValues(t.name))
|
||||
defer func() {
|
||||
_ = conn.Close()
|
||||
t.currentConnectionsCount.Done()
|
||||
openConnectionsGauge.WithLabelValues(t.name).Dec()
|
||||
timer.ObserveDuration()
|
||||
}()
|
||||
|
||||
rAddr, err := net.ResolveTCPAddr("tcp", t.options.redirectionTarget.address())
|
||||
rAddr, err := net.ResolveTCPAddr("tcp", t.options.Target.address())
|
||||
if err != nil {
|
||||
t.logger.Error(
|
||||
"failed to resolve proxy target",
|
||||
"failed to resolve proxy Target",
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
|
@ -114,7 +126,7 @@ func (t *tlsInterceptor) proxyConn(conn net.Conn) {
|
|||
targetConn, err := net.DialTCP("tcp", nil, rAddr)
|
||||
if err != nil {
|
||||
t.logger.Error(
|
||||
"failed to connect to proxy target",
|
||||
"failed to connect to proxy Target",
|
||||
zap.Error(err),
|
||||
)
|
||||
return
|
||||
|
|
|
@ -3,17 +3,40 @@ package tls_interceptor
|
|||
import (
|
||||
"github.com/baez90/inetmock/pkg/api"
|
||||
"github.com/baez90/inetmock/pkg/logging"
|
||||
"github.com/baez90/inetmock/pkg/metrics"
|
||||
"github.com/google/uuid"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"go.uber.org/zap"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
labelNames = []string{"handler_name"}
|
||||
handledRequestCounter *prometheus.CounterVec
|
||||
openConnectionsGauge *prometheus.GaugeVec
|
||||
requestDurationHistogram *prometheus.HistogramVec
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger, _ := logging.CreateLogger()
|
||||
var err error
|
||||
var logger logging.Logger
|
||||
if logger, err = logging.CreateLogger(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
logger = logger.With(
|
||||
zap.String("ProtocolHandler", name),
|
||||
zap.String("protocol_handler", name),
|
||||
)
|
||||
|
||||
if handledRequestCounter, err = metrics.Counter(name, "handled_requests", "", labelNames...); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if openConnectionsGauge, err = metrics.Gauge(name, "open_connections", "", labelNames...); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if requestDurationHistogram, err = metrics.Histogram(name, "request_duration", "", nil, labelNames...); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
api.Registry().RegisterHandler(name, func() api.ProtocolHandler {
|
||||
return &tlsInterceptor{
|
||||
logger: logger,
|
||||
|
|
|
@ -2,32 +2,17 @@ package tls_interceptor
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
targetIpAddressConfigKey = "target.ipAddress"
|
||||
targetPortConfigKey = "target.port"
|
||||
)
|
||||
|
||||
type redirectionTarget struct {
|
||||
ipAddress string
|
||||
port uint16
|
||||
IPAddress string
|
||||
Port uint16
|
||||
}
|
||||
|
||||
func (rt redirectionTarget) address() string {
|
||||
return fmt.Sprintf("%s:%d", rt.ipAddress, rt.port)
|
||||
return fmt.Sprintf("%s:%d", rt.IPAddress, rt.Port)
|
||||
}
|
||||
|
||||
type tlsOptions struct {
|
||||
redirectionTarget redirectionTarget
|
||||
}
|
||||
|
||||
func loadFromConfig(config *viper.Viper) tlsOptions {
|
||||
return tlsOptions{
|
||||
redirectionTarget: redirectionTarget{
|
||||
ipAddress: config.GetString(targetIpAddressConfigKey),
|
||||
port: uint16(config.GetInt(targetPortConfigKey)),
|
||||
},
|
||||
}
|
||||
Target redirectionTarget
|
||||
}
|
||||
|
|
|
@ -2,14 +2,22 @@ package tls_interceptor
|
|||
|
||||
import (
|
||||
"net"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
bufferPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return make([]byte, 1024)
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func chanFromConn(conn net.Conn) chan []byte {
|
||||
c := make(chan []byte)
|
||||
|
||||
go func() {
|
||||
b := make([]byte, 1024)
|
||||
|
||||
b := bufferPool.Get().([]byte)
|
||||
for {
|
||||
n, err := conn.Read(b)
|
||||
if n > 0 {
|
||||
|
|
|
@ -13,7 +13,7 @@ type proxyConn struct {
|
|||
func (p *proxyConn) Close() error {
|
||||
var err error
|
||||
if targetErr := p.target.Close(); targetErr != nil {
|
||||
err = fmt.Errorf("error while closing target conn: %w", targetErr)
|
||||
err = fmt.Errorf("error while closing Target conn: %w", targetErr)
|
||||
}
|
||||
if sourceErr := p.source.Close(); sourceErr != nil {
|
||||
err = fmt.Errorf("error while closing source conn: %w", err)
|
||||
|
|
Loading…
Reference in a new issue