mirror of
https://github.com/bloomberg/goldpinger.git
synced 2026-02-19 20:39:53 +00:00
Compare commits
106 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c66050e536 | ||
|
|
34d84b233c | ||
|
|
e07ae6a64c | ||
|
|
6844a8d2b4 | ||
|
|
c23112de50 | ||
|
|
436c1a7243 | ||
|
|
66c8dc0cce | ||
|
|
8a7e5a36ba | ||
|
|
4e508cb8c8 | ||
|
|
536a7ffbbb | ||
|
|
bf25a51c3e | ||
|
|
02b38e3ab7 | ||
|
|
0870833cf5 | ||
|
|
d5400d6e2e | ||
|
|
94d4a7c81e | ||
|
|
94dc18c9c2 | ||
|
|
8964cab729 | ||
|
|
d297e2f3c6 | ||
|
|
02067f03ab | ||
|
|
b96cab34ea | ||
|
|
bc7afb7a17 | ||
|
|
89a6c76c9c | ||
|
|
60436daf18 | ||
|
|
618369f540 | ||
|
|
1ab777c3d5 | ||
|
|
6315c71a2c | ||
|
|
49a47284b6 | ||
|
|
ec2155878a | ||
|
|
cab268b725 | ||
|
|
e552b236a0 | ||
|
|
8a86a74478 | ||
|
|
4dab241ff6 | ||
|
|
f99ba84d17 | ||
|
|
75315a872a | ||
|
|
ae67cf3594 | ||
|
|
433a6b8b88 | ||
|
|
0660db7922 | ||
|
|
58285945f6 | ||
|
|
8a014ad7f4 | ||
|
|
096b149afa | ||
|
|
5840353d9f | ||
|
|
ac9bf4224d | ||
|
|
bcbc2ac6fc | ||
|
|
192fc433a2 | ||
|
|
dc3864f170 | ||
|
|
8a759433eb | ||
|
|
1b12b7dc6b | ||
|
|
9adf26e2cb | ||
|
|
927125bbc5 | ||
|
|
7585d010a6 | ||
|
|
5e0ecdd8d1 | ||
|
|
d834433d30 | ||
|
|
b64f5152f2 | ||
|
|
bbac97c17e | ||
|
|
74ffcc8d2e | ||
|
|
9586e16237 | ||
|
|
6541250aa9 | ||
|
|
31a503d831 | ||
|
|
195691518b | ||
|
|
aa66c94d47 | ||
|
|
7b2affea29 | ||
|
|
d1a86eae93 | ||
|
|
a2e5925210 | ||
|
|
d243f0fb59 | ||
|
|
477ba69a72 | ||
|
|
86064f208e | ||
|
|
d8f8c20927 | ||
|
|
7c43626b1e | ||
|
|
11ec058b3b | ||
|
|
c006eede86 | ||
|
|
a585b103f3 | ||
|
|
32823fd105 | ||
|
|
87792cffca | ||
|
|
369e9ece78 | ||
|
|
28af41e352 | ||
|
|
52ea5546aa | ||
|
|
9040b69933 | ||
|
|
3ce0c46f91 | ||
|
|
7b156add72 | ||
|
|
8b1dd49506 | ||
|
|
bd13d4d673 | ||
|
|
895af850a1 | ||
|
|
771f303062 | ||
|
|
b7c1d2dfb4 | ||
|
|
86ddcf9505 | ||
|
|
bf43dcff98 | ||
|
|
6de72deee0 | ||
|
|
6cd12ef2d5 | ||
|
|
8182369c02 | ||
|
|
82a0d6ae8c | ||
|
|
057e360c5b | ||
|
|
4cf5dea621 | ||
|
|
16a1d52741 | ||
|
|
0472791dae | ||
|
|
84a43a3d28 | ||
|
|
3f70a24804 | ||
|
|
593307dc01 | ||
|
|
950e2e4ab7 | ||
|
|
d8f0d696ea | ||
|
|
6deb5c3044 | ||
|
|
767d2dba7f | ||
|
|
2efee0f5e5 | ||
|
|
3a729bf196 | ||
|
|
fd84599157 | ||
|
|
f5c2763000 | ||
|
|
22b96d001d |
@@ -1,2 +1 @@
|
||||
.git/
|
||||
/vendor/
|
||||
|
||||
24
.travis.yml
24
.travis.yml
@@ -4,23 +4,35 @@ services:
|
||||
- docker
|
||||
|
||||
go:
|
||||
- "1.10.x"
|
||||
- "1.14.x"
|
||||
- master
|
||||
|
||||
script:
|
||||
- docker --version
|
||||
# dep
|
||||
- go get -u github.com/golang/dep/cmd/dep
|
||||
|
||||
|
||||
# build locally and run locally
|
||||
- make clean && make vendor && make && ./bin/goldpinger --help
|
||||
|
||||
|
||||
# build an image and run the image
|
||||
- make clean && make vendor && make build
|
||||
- docker images
|
||||
- docker run `make version` --help
|
||||
|
||||
|
||||
# build an image using the multistage builder
|
||||
- make clean && make build-multistage
|
||||
- docker images
|
||||
- docker run `make version` --help
|
||||
|
||||
# build an image with the vendor folder
|
||||
- make clean && make vendor && make vendor-build
|
||||
- docker images
|
||||
- docker run `make version`-vendor --help
|
||||
|
||||
deploy:
|
||||
provider: script
|
||||
script: bash docker_deploy.sh
|
||||
skip_cleanup: true
|
||||
on:
|
||||
tags: true
|
||||
go: "1.14.x"
|
||||
condition: -n "$DOCKER_PASSWORD"
|
||||
|
||||
12
Dockerfile
12
Dockerfile
@@ -1,15 +1,14 @@
|
||||
FROM golang:1.11-alpine as builder
|
||||
FROM golang:1.14-alpine as builder
|
||||
|
||||
# Install our build tools
|
||||
|
||||
RUN apk add --update git make bash
|
||||
RUN go get -u github.com/golang/dep/cmd/dep
|
||||
|
||||
# Get dependencies
|
||||
|
||||
WORKDIR /go/src/github.com/bloomberg/goldpinger
|
||||
COPY Gopkg.toml Gopkg.lock Makefile ./
|
||||
RUN make vendor
|
||||
WORKDIR /w
|
||||
COPY go.mod go.sum /w/
|
||||
RUN go mod download
|
||||
|
||||
# Build goldpinger
|
||||
|
||||
@@ -19,7 +18,6 @@ RUN make bin/goldpinger
|
||||
# Build the asset container, copy over goldpinger
|
||||
|
||||
FROM scratch
|
||||
COPY --from=builder /go/src/github.com/bloomberg/goldpinger/bin/goldpinger /goldpinger
|
||||
COPY --from=builder /w/bin/goldpinger /goldpinger
|
||||
COPY ./static /static
|
||||
ENTRYPOINT ["/goldpinger", "--static-file-path", "/static"]
|
||||
|
||||
|
||||
637
Gopkg.lock
generated
637
Gopkg.lock
generated
@@ -1,637 +0,0 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d1665c44bd5db19aaee18d1b6233c99b0b9a986e8bccb24ef54747547a48027f"
|
||||
name = "github.com/PuerkitoBio/purell"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "0bcb03f4b4d0a9428594752bd2a3b9aa0a9d4bd4"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:c739832d67eb1e9cc478a19cc1a1ccd78df0397bf8a32978b759152e205f644b"
|
||||
name = "github.com/PuerkitoBio/urlesc"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "de5bf2ad457846296e2031421a34e2568e304e35"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:320e7ead93de9fd2b0e59b50fd92a4d50c1f8ab455d96bc2eb083267453a9709"
|
||||
name = "github.com/asaskevich/govalidator"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "ccb8e960c48f04d6935e72476ae4a51028f9e22f"
|
||||
version = "v9"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:d6afaeed1502aa28e80a4ed0981d570ad91b2579193404256ce672ed0a609e0d"
|
||||
name = "github.com/beorn7/perks"
|
||||
packages = ["quantile"]
|
||||
pruneopts = "UT"
|
||||
revision = "3a771d992973f24aa725d07868b467d1ddfceafb"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:6f82cacd0af5921e99bf3f46748705239b36489464f4529a1589bc895764fb18"
|
||||
name = "github.com/docker/go-units"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "47565b4f722fb6ceae66b95f853feed578a4a51c"
|
||||
version = "v0.3.3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c45cef8e0074ea2f8176a051df38553ba997a3616f1ec2d35222b1cf9864881e"
|
||||
name = "github.com/ghodss/yaml"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "73d445a93680fa1a78ae23a5839bad48f32ba1ee"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:7fb51688eadf38272411852d7a2b3538c7caff53309abee6c0964a83c00fe69e"
|
||||
name = "github.com/globalsign/mgo"
|
||||
packages = [
|
||||
"bson",
|
||||
"internal/json",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "eeefdecb41b842af6dc652aaea4026e8403e62df"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c49164b7b1e34324258ae61deef2cba7912005ba9cb7a9ee4930fe6bdfec7b5d"
|
||||
name = "github.com/go-openapi/analysis"
|
||||
packages = [
|
||||
".",
|
||||
"internal",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "c701774f4e604d952e4e8c56dee260be696e33c3"
|
||||
version = "v0.17.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ac4b35a4bba11edb2110fca0707bae03ae92fbd8222e6b483465d98efaabfb97"
|
||||
name = "github.com/go-openapi/errors"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "d9664f9fab8994271e573ed69cf2adfc09b7a800"
|
||||
version = "v0.17.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:953a2628e4c5c72856b53f5470ed5e071c55eccf943d798d42908102af2a610f"
|
||||
name = "github.com/go-openapi/jsonpointer"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "ef5f0afec364d3b9396b7b77b43dbe26bf1f8004"
|
||||
version = "v0.17.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:81210e0af657a0fb3638932ec68e645236bceefa4c839823db0c4d918f080895"
|
||||
name = "github.com/go-openapi/jsonreference"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "8483a886a90412cd6858df4ea3483dce9c8e35a3"
|
||||
version = "v0.17.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a20e8bf0e58e2010677432ffbe5533c1e83bdf368ba5b057f3e00e2071ca8b09"
|
||||
name = "github.com/go-openapi/loads"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "150d36912387ec2f607be674c5be309ddccc0eed"
|
||||
version = "v0.17.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:76b781f51e08cc0494b4abacf70d4b9da0a4732e270b7f2045ca9f0f875ad6d1"
|
||||
name = "github.com/go-openapi/runtime"
|
||||
packages = [
|
||||
".",
|
||||
"client",
|
||||
"flagext",
|
||||
"logger",
|
||||
"middleware",
|
||||
"middleware/denco",
|
||||
"middleware/header",
|
||||
"middleware/untyped",
|
||||
"security",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "231d7876b7019dbcbfc97a7ba764379497b67c1d"
|
||||
version = "v0.17.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:394fed5c0425fe01da3a34078adaa1682e4deaea6e5d232dde25c4034004c151"
|
||||
name = "github.com/go-openapi/spec"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "5bae59e25b21498baea7f9d46e9c147ec106a42e"
|
||||
version = "v0.17.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ffa79f4705a3a85f2412d2d163c37acdf60d128c679e641c323a5de712e23d27"
|
||||
name = "github.com/go-openapi/strfmt"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "edab9990ffc9b4a428f3306ecf4d18a069ca3317"
|
||||
version = "v0.17.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:32f3d2e7f343de7263c550d696fb8a64d3c49d8df16b1ddfc8e80e1e4b3233ce"
|
||||
name = "github.com/go-openapi/swag"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "5899d5c5e619fda5fa86e14795a835f473ca284c"
|
||||
version = "v0.17.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:58541fddf3f4ec485710f1b346e7f647baf09a878a604e47e3668c600fe44076"
|
||||
name = "github.com/go-openapi/validate"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "d2eab7d93009e9215fc85b2faa2c2f2a98c2af48"
|
||||
version = "v0.17.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f83d740263b44fdeef3e1bce6147b5d7283fcad1a693d39639be33993ecf3db1"
|
||||
name = "github.com/gogo/protobuf"
|
||||
packages = [
|
||||
"proto",
|
||||
"sortkeys",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2edd2416f89b4e841df0e4a78802ce14d2bc7ad79eba1a45986e39f0f8cb7d87"
|
||||
name = "github.com/golang/glog"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "44145f04b68cf362d9c4df2182967c2275eaefed"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:4c0989ca0bcd10799064318923b9bc2db6b4d6338dd75f3f2d86c3511aaaf5cf"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = [
|
||||
"proto",
|
||||
"ptypes",
|
||||
"ptypes/any",
|
||||
"ptypes/duration",
|
||||
"ptypes/timestamp",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "aa810b61a9c79d51363740d207bb46cf8e620ed5"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:0bfbe13936953a98ae3cfe8ed6670d396ad81edf069a806d2f6515d7bb6950df"
|
||||
name = "github.com/google/btree"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "4030bb1f1f0c35b30ca7009e9ebd06849dd45306"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:41bfd4219241b7f7d6e6fdb13fc712576f1337e68e6b895136283b76928fdd66"
|
||||
name = "github.com/google/gofuzz"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "44d81051d367757e1c7c6a5a86423ece9afcf63c"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:75eb87381d25cc75212f52358df9c3a2719584eaa9685cd510ce28699122f39d"
|
||||
name = "github.com/googleapis/gnostic"
|
||||
packages = [
|
||||
"OpenAPIv2",
|
||||
"compiler",
|
||||
"extensions",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "0c5108395e2debce0d731cf0287ddf7242066aba"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:878f0defa9b853f9acfaf4a162ba450a89d0050eff084f9fe7f5bd15948f172a"
|
||||
name = "github.com/gregjones/httpcache"
|
||||
packages = [
|
||||
".",
|
||||
"diskcache",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "787624de3eb7bd915c329cba748687a3b22666a6"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3e260afa138eab6492b531a3b3d10ab4cb70512d423faa78b8949dec76e66a21"
|
||||
name = "github.com/imdario/mergo"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "9316a62528ac99aaecb4e47eadd6dc8aa6533d58"
|
||||
version = "v0.3.5"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a2cff208d4759f6ba1b1cd228587b0a1869f95f22542ec9cd17fff64430113c7"
|
||||
name = "github.com/jessevdk/go-flags"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "c6ca198ec95c841fdb89fc0de7496fed11ab854e"
|
||||
version = "v1.4.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:bb3cc4c1b21ea18cfa4e3e47440fc74d316ab25b0cf42927e8c1274917bd9891"
|
||||
name = "github.com/json-iterator/go"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "f2b4162afba35581b6d4a50d3b8f34e33c144682"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:84a5a2b67486d5d67060ac393aa255d05d24ed5ee41daecd5635ec22657b6492"
|
||||
name = "github.com/mailru/easyjson"
|
||||
packages = [
|
||||
"buffer",
|
||||
"jlexer",
|
||||
"jwriter",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "60711f1a8329503b04e1c88535f419d0bb440bff"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ff5ebae34cfbf047d505ee150de27e60570e8c394b3b8fdbb720ff6ac71985fc"
|
||||
name = "github.com/matttproud/golang_protobuf_extensions"
|
||||
packages = ["pbutil"]
|
||||
pruneopts = "UT"
|
||||
revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:53bc4cd4914cd7cd52139990d5170d6dc99067ae31c56530621b18b35fc30318"
|
||||
name = "github.com/mitchellh/mapstructure"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "3536a929edddb9a5b34bd6861dc4a9647cb459fe"
|
||||
version = "v1.1.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:33422d238f147d247752996a26574ac48dcf472976eda7f5134015f06bf16563"
|
||||
name = "github.com/modern-go/concurrent"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94"
|
||||
version = "1.0.3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e32bdbdb7c377a07a9a46378290059822efdce5c8d96fe71940d87cb4f918855"
|
||||
name = "github.com/modern-go/reflect2"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd"
|
||||
version = "1.0.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:3bf17a6e6eaa6ad24152148a631d18662f7212e21637c2699bff3369b7f00fa2"
|
||||
name = "github.com/petar/GoLLRB"
|
||||
packages = ["llrb"]
|
||||
pruneopts = "UT"
|
||||
revision = "53be0d36a84c2a886ca057d34b6aa4468df9ccb4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0e7775ebbcf00d8dd28ac663614af924411c868dca3d5aa762af0fae3808d852"
|
||||
name = "github.com/peterbourgon/diskv"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "5f041e8faa004a95c88a202771f4cc3e991971e6"
|
||||
version = "v2.0.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:26663fafdea73a38075b07e8e9d82fc0056379d2be8bb4e13899e8fda7c7dd23"
|
||||
name = "github.com/prometheus/client_golang"
|
||||
packages = [
|
||||
"prometheus",
|
||||
"prometheus/internal",
|
||||
"prometheus/promhttp",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "abad2d1bd44235a26707c172eab6bca5bf2dbad3"
|
||||
version = "v0.9.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:2d5cd61daa5565187e1d96bae64dbbc6080dacf741448e9629c64fd93203b0d4"
|
||||
name = "github.com/prometheus/client_model"
|
||||
packages = ["go"]
|
||||
pruneopts = "UT"
|
||||
revision = "5c3871d89910bfb32f5fcab2aa4b9ec68e65a99f"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:db712fde5d12d6cdbdf14b777f0c230f4ff5ab0be8e35b239fc319953ed577a4"
|
||||
name = "github.com/prometheus/common"
|
||||
packages = [
|
||||
"expfmt",
|
||||
"internal/bitbucket.org/ww/goautoneg",
|
||||
"model",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "7e9e6cabbd393fc208072eedef99188d0ce788b6"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:ef74914912f99c79434d9c09658274678bc85080ebe3ab32bec3940ebce5e1fc"
|
||||
name = "github.com/prometheus/procfs"
|
||||
packages = [
|
||||
".",
|
||||
"internal/util",
|
||||
"nfs",
|
||||
"xfs",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "185b4288413d2a0dd0806f78c90dde719829e5ae"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:9424f440bba8f7508b69414634aef3b2b3a877e522d8a4624692412805407bb7"
|
||||
name = "github.com/spf13/pflag"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "583c0c0531f06d5278b7d917446061adc344b5cd"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3f3a05ae0b95893d90b9b3b5afdb79a9b3d96e4e36e099d841ae602e4aca0da8"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = ["ssh/terminal"]
|
||||
pruneopts = "UT"
|
||||
revision = "de0752318171da717af4ce24d0a2e8626afaeb11"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:eb8583d4582ffbc5c6d3ec00132cd0835101edde42b6f24eaafa628d1596f881"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"context",
|
||||
"http/httpguts",
|
||||
"http2",
|
||||
"http2/hpack",
|
||||
"idna",
|
||||
"netutil",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "10aee181995363b41f712a55844a0dd52ea04646"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:9359217acc6040b4be710ce34473acef28023ad39bfafecea34ffaea7f1e1890"
|
||||
name = "golang.org/x/oauth2"
|
||||
packages = [
|
||||
".",
|
||||
"internal",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "a6bd8cefa1811bd24b86f8902872e4e8225f74c4"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:509feef845f6af582cb82caad5eb176016b30714facdc754d84869ca31305b59"
|
||||
name = "golang.org/x/sys"
|
||||
packages = [
|
||||
"unix",
|
||||
"windows",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "7155702f2d47d94b134229da97195d0130cab001"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0c56024909189aee3364b7f21a95a27459f718aa7c199a5c111c36cfffd9eaef"
|
||||
name = "golang.org/x/text"
|
||||
packages = [
|
||||
"collate",
|
||||
"collate/build",
|
||||
"internal/colltab",
|
||||
"internal/gen",
|
||||
"internal/tag",
|
||||
"internal/triegen",
|
||||
"internal/ucd",
|
||||
"language",
|
||||
"secure/bidirule",
|
||||
"transform",
|
||||
"unicode/bidi",
|
||||
"unicode/cldr",
|
||||
"unicode/norm",
|
||||
"unicode/rangetable",
|
||||
"width",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
|
||||
version = "v0.3.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d37b0ef2944431fe9e8ef35c6fffc8990d9e2ca300588df94a6890f3649ae365"
|
||||
name = "golang.org/x/time"
|
||||
packages = ["rate"]
|
||||
pruneopts = "UT"
|
||||
revision = "f51c12702a4d776e4c1fa9b0fabab841babae631"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:08206298775e5b462e6c0333f4471b44e63f1a70e42952b6ede4ecc9572281eb"
|
||||
name = "google.golang.org/appengine"
|
||||
packages = [
|
||||
"internal",
|
||||
"internal/base",
|
||||
"internal/datastore",
|
||||
"internal/log",
|
||||
"internal/remote_api",
|
||||
"internal/urlfetch",
|
||||
"urlfetch",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "4a4468ece617fc8205e99368fa2200e9d1fad421"
|
||||
version = "v1.3.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ef72505cf098abdd34efeea032103377bec06abb61d8a06f002d5d296a4b1185"
|
||||
name = "gopkg.in/inf.v0"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4"
|
||||
version = "v0.9.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:342378ac4dcb378a5448dd723f0784ae519383532f5e70ade24132c4c8693202"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
|
||||
version = "v2.2.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:910ec974550174f4ca48b9f4a3caec16b693e584c3762dc726dc0dcf28f8e318"
|
||||
name = "k8s.io/api"
|
||||
packages = [
|
||||
"admissionregistration/v1alpha1",
|
||||
"admissionregistration/v1beta1",
|
||||
"apps/v1",
|
||||
"apps/v1beta1",
|
||||
"apps/v1beta2",
|
||||
"authentication/v1",
|
||||
"authentication/v1beta1",
|
||||
"authorization/v1",
|
||||
"authorization/v1beta1",
|
||||
"autoscaling/v1",
|
||||
"autoscaling/v2beta1",
|
||||
"autoscaling/v2beta2",
|
||||
"batch/v1",
|
||||
"batch/v1beta1",
|
||||
"batch/v2alpha1",
|
||||
"certificates/v1beta1",
|
||||
"coordination/v1beta1",
|
||||
"core/v1",
|
||||
"events/v1beta1",
|
||||
"extensions/v1beta1",
|
||||
"networking/v1",
|
||||
"policy/v1beta1",
|
||||
"rbac/v1",
|
||||
"rbac/v1alpha1",
|
||||
"rbac/v1beta1",
|
||||
"scheduling/v1alpha1",
|
||||
"scheduling/v1beta1",
|
||||
"settings/v1alpha1",
|
||||
"storage/v1",
|
||||
"storage/v1alpha1",
|
||||
"storage/v1beta1",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
version = "kubernetes-1.12.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:18f352651d6e8578fdbaf29c68334b042439b288b8ae4112c2b2ba9a6e35ced0"
|
||||
name = "k8s.io/apimachinery"
|
||||
packages = [
|
||||
"pkg/api/errors",
|
||||
"pkg/api/meta",
|
||||
"pkg/api/resource",
|
||||
"pkg/apis/meta/v1",
|
||||
"pkg/apis/meta/v1/unstructured",
|
||||
"pkg/apis/meta/v1beta1",
|
||||
"pkg/conversion",
|
||||
"pkg/conversion/queryparams",
|
||||
"pkg/fields",
|
||||
"pkg/labels",
|
||||
"pkg/runtime",
|
||||
"pkg/runtime/schema",
|
||||
"pkg/runtime/serializer",
|
||||
"pkg/runtime/serializer/json",
|
||||
"pkg/runtime/serializer/protobuf",
|
||||
"pkg/runtime/serializer/recognizer",
|
||||
"pkg/runtime/serializer/streaming",
|
||||
"pkg/runtime/serializer/versioning",
|
||||
"pkg/selection",
|
||||
"pkg/types",
|
||||
"pkg/util/clock",
|
||||
"pkg/util/errors",
|
||||
"pkg/util/framer",
|
||||
"pkg/util/intstr",
|
||||
"pkg/util/json",
|
||||
"pkg/util/naming",
|
||||
"pkg/util/net",
|
||||
"pkg/util/runtime",
|
||||
"pkg/util/sets",
|
||||
"pkg/util/validation",
|
||||
"pkg/util/validation/field",
|
||||
"pkg/util/yaml",
|
||||
"pkg/version",
|
||||
"pkg/watch",
|
||||
"third_party/forked/golang/reflect",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
version = "kubernetes-1.12.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:51fd9ac9f2be10d79f5af101a7a1d758ef283fdb028a0d11198754bd3d4a6020"
|
||||
name = "k8s.io/client-go"
|
||||
packages = [
|
||||
"discovery",
|
||||
"kubernetes",
|
||||
"kubernetes/scheme",
|
||||
"kubernetes/typed/admissionregistration/v1alpha1",
|
||||
"kubernetes/typed/admissionregistration/v1beta1",
|
||||
"kubernetes/typed/apps/v1",
|
||||
"kubernetes/typed/apps/v1beta1",
|
||||
"kubernetes/typed/apps/v1beta2",
|
||||
"kubernetes/typed/authentication/v1",
|
||||
"kubernetes/typed/authentication/v1beta1",
|
||||
"kubernetes/typed/authorization/v1",
|
||||
"kubernetes/typed/authorization/v1beta1",
|
||||
"kubernetes/typed/autoscaling/v1",
|
||||
"kubernetes/typed/autoscaling/v2beta1",
|
||||
"kubernetes/typed/autoscaling/v2beta2",
|
||||
"kubernetes/typed/batch/v1",
|
||||
"kubernetes/typed/batch/v1beta1",
|
||||
"kubernetes/typed/batch/v2alpha1",
|
||||
"kubernetes/typed/certificates/v1beta1",
|
||||
"kubernetes/typed/coordination/v1beta1",
|
||||
"kubernetes/typed/core/v1",
|
||||
"kubernetes/typed/events/v1beta1",
|
||||
"kubernetes/typed/extensions/v1beta1",
|
||||
"kubernetes/typed/networking/v1",
|
||||
"kubernetes/typed/policy/v1beta1",
|
||||
"kubernetes/typed/rbac/v1",
|
||||
"kubernetes/typed/rbac/v1alpha1",
|
||||
"kubernetes/typed/rbac/v1beta1",
|
||||
"kubernetes/typed/scheduling/v1alpha1",
|
||||
"kubernetes/typed/scheduling/v1beta1",
|
||||
"kubernetes/typed/settings/v1alpha1",
|
||||
"kubernetes/typed/storage/v1",
|
||||
"kubernetes/typed/storage/v1alpha1",
|
||||
"kubernetes/typed/storage/v1beta1",
|
||||
"pkg/apis/clientauthentication",
|
||||
"pkg/apis/clientauthentication/v1alpha1",
|
||||
"pkg/apis/clientauthentication/v1beta1",
|
||||
"pkg/version",
|
||||
"plugin/pkg/client/auth/exec",
|
||||
"rest",
|
||||
"rest/watch",
|
||||
"tools/auth",
|
||||
"tools/clientcmd",
|
||||
"tools/clientcmd/api",
|
||||
"tools/clientcmd/api/latest",
|
||||
"tools/clientcmd/api/v1",
|
||||
"tools/metrics",
|
||||
"tools/reference",
|
||||
"transport",
|
||||
"util/cert",
|
||||
"util/connrotation",
|
||||
"util/flowcontrol",
|
||||
"util/homedir",
|
||||
"util/integer",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "1638f8970cefaa404ff3a62950f88b08292b2696"
|
||||
version = "v9.0.0"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
input-imports = [
|
||||
"github.com/go-openapi/errors",
|
||||
"github.com/go-openapi/loads",
|
||||
"github.com/go-openapi/runtime",
|
||||
"github.com/go-openapi/runtime/client",
|
||||
"github.com/go-openapi/runtime/flagext",
|
||||
"github.com/go-openapi/runtime/middleware",
|
||||
"github.com/go-openapi/runtime/security",
|
||||
"github.com/go-openapi/spec",
|
||||
"github.com/go-openapi/strfmt",
|
||||
"github.com/go-openapi/swag",
|
||||
"github.com/go-openapi/validate",
|
||||
"github.com/jessevdk/go-flags",
|
||||
"github.com/prometheus/client_golang/prometheus",
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp",
|
||||
"golang.org/x/net/context",
|
||||
"golang.org/x/net/netutil",
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"k8s.io/client-go/kubernetes",
|
||||
"k8s.io/client-go/rest",
|
||||
"k8s.io/client-go/tools/clientcmd",
|
||||
]
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
78
Gopkg.toml
78
Gopkg.toml
@@ -1,78 +0,0 @@
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
#
|
||||
# [prune]
|
||||
# non-go = false
|
||||
# go-tests = true
|
||||
# unused-packages = true
|
||||
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/go-openapi/errors"
|
||||
version = "0.17.2"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/go-openapi/loads"
|
||||
version = "0.17.2"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/go-openapi/runtime"
|
||||
version = "0.17.2"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/go-openapi/spec"
|
||||
version = "0.17.2"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/go-openapi/strfmt"
|
||||
version = "0.17.2"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/go-openapi/swag"
|
||||
version = "0.17.2"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/go-openapi/validate"
|
||||
version = "0.17.2"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/jessevdk/go-flags"
|
||||
version = "1.4.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/prometheus/client_golang"
|
||||
version = "0.9.1"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/net"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/apimachinery"
|
||||
version = "kubernetes-1.12.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/client-go"
|
||||
version = "9.0.0"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
21
Makefile
21
Makefile
@@ -1,10 +1,10 @@
|
||||
name ?= goldpinger
|
||||
version ?= 1.3.0
|
||||
version ?= v2.1.0
|
||||
bin ?= goldpinger
|
||||
pkg ?= "github.com/bloomberg/goldpinger"
|
||||
tag = $(name):$(version)
|
||||
goos ?= ${GOOS}
|
||||
namespace ?= ""
|
||||
namespace ?= "bloomberg/"
|
||||
files = $(shell find . -iname "*.go")
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ clean:
|
||||
|
||||
vendor:
|
||||
rm -rf ./vendor
|
||||
dep ensure -v -vendor-only
|
||||
go mod vendor
|
||||
|
||||
swagger:
|
||||
swagger generate server -t pkg -f ./swagger.yml --exclude-main -A goldpinger && \
|
||||
@@ -38,8 +38,19 @@ push:
|
||||
|
||||
run:
|
||||
go run ./cmd/goldpinger/main.go
|
||||
|
||||
|
||||
version:
|
||||
@echo $(tag)
|
||||
|
||||
.PHONY: clean vendor swagger build build-multistage tag push run version
|
||||
|
||||
vendor-build:
|
||||
docker build -t $(tag)-vendor --build-arg TAG=$(tag) -f ./build/Dockerfile-vendor .
|
||||
|
||||
vendor-tag:
|
||||
docker tag $(tag)-vendor $(namespace)$(tag)-vendor
|
||||
|
||||
vendor-push:
|
||||
docker push $(namespace)$(tag)-vendor
|
||||
|
||||
|
||||
.PHONY: clean vendor swagger build build-multistage vendor-build vendor-tag vendor-push tag push run version
|
||||
|
||||
144
README.md
144
README.md
@@ -10,22 +10,25 @@ Oh, and it gives you the graph below for your cluster. Check out the [video expl
|
||||
|
||||
## On the menu
|
||||
|
||||
- [Rationale](#rationale)
|
||||
- [Quick start](#quick-start)
|
||||
- [Building](#building)
|
||||
- [Compiling using a multi-stage Dockerfile](#compiling-using-a-multi-stage-dockerfile)
|
||||
- [Compiling locally](#compiling-locally)
|
||||
- [Installation](#installation)
|
||||
- [Authentication with Kubernetes API](#authentication-with-kubernetes-api)
|
||||
- [Example YAML](#example-yaml)
|
||||
- [Usage](#usage)
|
||||
- [UI](#ui)
|
||||
- [API](#api)
|
||||
- [Prometheus](#prometheus)
|
||||
- [Grafana](#grafana)
|
||||
- [Alert Manager](#alert-manager)
|
||||
- [Contributions](#contributions)
|
||||
- [License](#license)
|
||||
- [Goldpinger ](#goldpinger-build-statushttpstravis-cicombloomberggoldpinger)
|
||||
- [On the menu](#on-the-menu)
|
||||
- [Rationale](#rationale)
|
||||
- [Quick start](#quick-start)
|
||||
- [Building](#building)
|
||||
- [Compiling using a multi-stage Dockerfile](#compiling-using-a-multi-stage-dockerfile)
|
||||
- [Compiling locally](#compiling-locally)
|
||||
- [Installation](#installation)
|
||||
- [Authentication with Kubernetes API](#authentication-with-kubernetes-api)
|
||||
- [Example YAML](#example-yaml)
|
||||
- [Note on DNS](#note-on-dns)
|
||||
- [Usage](#usage)
|
||||
- [UI](#ui)
|
||||
- [API](#api)
|
||||
- [Prometheus](#prometheus)
|
||||
- [Grafana](#grafana)
|
||||
- [Alert Manager](#alert-manager)
|
||||
- [Contributions](#contributions)
|
||||
- [License](#license)
|
||||
|
||||
## Rationale
|
||||
|
||||
@@ -38,13 +41,19 @@ If you'd like to know more, you can watch [our presentation at Kubecon 2018 Seat
|
||||
|
||||
## Quick start
|
||||
|
||||
Getting from sources:
|
||||
|
||||
```sh
|
||||
go get github.com/bloomberg/goldpinger/cmd/goldpinger
|
||||
goldpinger --help
|
||||
```
|
||||
|
||||
Note, that in order to guarantee correct versions of dependencies, the project [uses `dep`](./Makefile).
|
||||
Getting from [docker hub](https://hub.docker.com/r/bloomberg/goldpinger):
|
||||
|
||||
```sh
|
||||
# get from docker hub
|
||||
docker pull bloomberg/goldpinger
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
@@ -67,27 +76,24 @@ This was contributed via [@michiel](https://github.com/michiel) - kudos !
|
||||
|
||||
### Compiling locally
|
||||
|
||||
In order to build `Goldpinger`, you are going to need `go` version 1.10+, `dep`, and `docker`.
|
||||
In order to build `Goldpinger`, you are going to need `go` version 1.13+ and `docker`.
|
||||
|
||||
Building from source code consists of compiling the binary and building a [Docker image](./build/Dockerfile-simple):
|
||||
|
||||
```sh
|
||||
# step 0: check out the code into your $GOPATH
|
||||
go get github.com/bloomberg/goldpinger/cmd/goldpinger
|
||||
cd $GOPATH/src/github.com/bloomberg/goldpinger
|
||||
# step 0: check out the code
|
||||
git clone https://github.com/bloomberg/goldpinger.git
|
||||
cd goldpinger
|
||||
|
||||
# step 1: download the dependencies via dep ensure
|
||||
make vendor
|
||||
|
||||
# step 2: compile the binary for the desired architecture
|
||||
# step 1: compile the binary for the desired architecture
|
||||
make bin/goldpinger
|
||||
# at this stage you should be able to run the binary
|
||||
./bin/goldpinger --help
|
||||
|
||||
# step 3: build the docker image containing the binary
|
||||
# step 2: build the docker image containing the binary
|
||||
make build
|
||||
|
||||
# step 4: push the image somewhere
|
||||
# step 3: push the image somewhere
|
||||
namespace="docker.io/myhandle/" make tag
|
||||
namespace="docker.io/myhandle/" make push
|
||||
```
|
||||
@@ -103,9 +109,7 @@ namespace="docker.io/myhandle/" make push
|
||||
### Example YAML
|
||||
|
||||
|
||||
Here's an example of what you can do (using the in-cluster authentication to `Kubernetes` apiserver).
|
||||
|
||||
:warning: Replace `docker.io/mynamespace-replaceme/goldpinger:1.0.0` with the actual tag you built.
|
||||
Here's an example of what you can do (using the in-cluster authentication to `Kubernetes` apiserver).
|
||||
|
||||
```yaml
|
||||
---
|
||||
@@ -113,46 +117,86 @@ apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: goldpinger
|
||||
namespace: default
|
||||
labels:
|
||||
app: goldpinger
|
||||
spec:
|
||||
updateStrategy:
|
||||
type: RollingUpdate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: goldpinger
|
||||
version: "1.0.0"
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
prometheus.io/scrape: 'true'
|
||||
prometheus.io/port: '8080'
|
||||
labels:
|
||||
app: goldpinger
|
||||
version: "1.0.0"
|
||||
spec:
|
||||
serviceAccount: "goldpinger-serviceaccount"
|
||||
tolerations:
|
||||
- key: node-role.kubernetes.io/master
|
||||
effect: NoSchedule
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
fsGroup: 2000
|
||||
containers:
|
||||
- name: goldpinger
|
||||
env:
|
||||
- name: HOST
|
||||
value: "0.0.0.0"
|
||||
- name: PORT
|
||||
value: "80"
|
||||
value: "8080"
|
||||
# injecting real hostname will make for easier to understand graphs/metrics
|
||||
- name: HOSTNAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
image: "docker.io/mynamespace-replaceme/goldpinger:1.0.0"
|
||||
# podIP is used to select a randomized subset of nodes to ping.
|
||||
- name: POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
image: "docker.io/bloomberg/goldpinger:2.0.2"
|
||||
imagePullPolicy: Always
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
resources:
|
||||
limits:
|
||||
memory: 80Mi
|
||||
requests:
|
||||
cpu: 1m
|
||||
memory: 40Mi
|
||||
ports:
|
||||
- containerPort: 80
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8080
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 5
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8080
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 5
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: goldpinger
|
||||
namespace: default
|
||||
labels:
|
||||
app: goldpinger
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 80
|
||||
- port: 8080
|
||||
nodePort: 30080
|
||||
name: http
|
||||
selector:
|
||||
@@ -179,6 +223,28 @@ subjects:
|
||||
|
||||
You can also see [an example of using `kubeconfig` in the `./extras`](./extras/example-with-kubeconfig.yaml).
|
||||
|
||||
### Note on DNS
|
||||
|
||||
Note, that on top of resolving the other pods, all instances can also try to resolve arbitrary DNS. This allows you to test your DNS setup.
|
||||
|
||||
From `--help`:
|
||||
|
||||
```sh
|
||||
--host-to-resolve= A host to attempt dns resolve on (space delimited) [$HOSTS_TO_RESOLVE]
|
||||
```
|
||||
|
||||
So in order to test two domains, we could add an extra env var to the example above:
|
||||
|
||||
```yaml
|
||||
- name: HOSTS_TO_RESOLVE
|
||||
value: "www.bloomberg.com one.two.three"
|
||||
```
|
||||
|
||||
and `goldpinger` should show something like this:
|
||||
|
||||

|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
### UI
|
||||
@@ -191,7 +257,7 @@ You can click on various nodes to gray out the clutter and see more information.
|
||||
|
||||
### API
|
||||
|
||||
The API exposed is via a well-defined [`Swagger` spec](./swagger.yml).
|
||||
The API exposed is via a well-defined [`Swagger` spec](./swagger.yml).
|
||||
|
||||
The spec is used to generate both the server and the client of `Goldpinger`. If you make changes, you can re-generate them using [go-swagger](https://github.com/go-swagger/go-swagger) via [`make swagger`](./Makefile)
|
||||
|
||||
@@ -224,7 +290,7 @@ To get you started, here's a rule that will trigger an alert if there are any no
|
||||
```yaml
|
||||
alert: goldpinger_nodes_unhealthy
|
||||
expr: sum(goldpinger_nodes_health_total{status="unhealthy"})
|
||||
BY (goldpinger_instance) > 0
|
||||
BY (instance, goldpinger_instance) > 0
|
||||
for: 5m
|
||||
annotations:
|
||||
description: |
|
||||
@@ -247,3 +313,5 @@ Before you create that PR, please make sure you read [CONTRIBUTING](./CONTRIBUTI
|
||||
## License
|
||||
|
||||
Please read the [LICENSE](./LICENSE) file here.
|
||||
|
||||
For each version built by travis, there is also an additional version, appended with `-vendor`, which contains all source code of the dependencies used in `goldpinger`.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
FROM scratch
|
||||
|
||||
ADD bin/goldpinger /goldpinger
|
||||
COPY static/index.html /static/index.html
|
||||
COPY bin/goldpinger /goldpinger
|
||||
COPY static /static
|
||||
|
||||
ENTRYPOINT ["/goldpinger", "--static-file-path", "/static"]
|
||||
|
||||
3
build/Dockerfile-vendor
Normal file
3
build/Dockerfile-vendor
Normal file
@@ -0,0 +1,3 @@
|
||||
ARG TAG
|
||||
FROM $TAG
|
||||
COPY vendor /goldpinger-vendor-sources
|
||||
@@ -96,6 +96,14 @@ func main() {
|
||||
goldpinger.GoldpingerConfig.Port = server.Port
|
||||
}
|
||||
|
||||
if goldpinger.GoldpingerConfig.PodIP == "" {
|
||||
log.Println("PodIP not set: pinging all pods")
|
||||
}
|
||||
if goldpinger.GoldpingerConfig.PingNumber == 0 {
|
||||
log.Println("--ping-number set to 0: pinging all pods")
|
||||
}
|
||||
goldpinger.GoldpingerConfig.PodSelecter = goldpinger.NewPodSelecter(goldpinger.GoldpingerConfig.PingNumber, goldpinger.GoldpingerConfig.PodIP, goldpinger.GetAllPods)
|
||||
|
||||
server.ConfigureAPI()
|
||||
goldpinger.StartUpdater()
|
||||
|
||||
|
||||
8
docker_deploy.sh
Executable file
8
docker_deploy.sh
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD" \
|
||||
&& make tag \
|
||||
&& make push \
|
||||
&& make vendor-tag \
|
||||
&& make vendor-push
|
||||
|
||||
BIN
extras/dns-screenshot.png
Normal file
BIN
extras/dns-screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 374 KiB |
@@ -1,4 +1,3 @@
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
@@ -26,22 +25,53 @@ spec:
|
||||
app: goldpinger
|
||||
spec:
|
||||
serviceAccount: "goldpinger-serviceaccount"
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
fsGroup: 2000
|
||||
containers:
|
||||
- name: goldpinger
|
||||
env:
|
||||
- name: HOST
|
||||
value: "0.0.0.0"
|
||||
- name: PORT
|
||||
value: "80"
|
||||
value: "8080"
|
||||
# injecting real hostname will make for easier to understand graphs/metrics
|
||||
- name: HOSTNAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
image: "docker.io/mynamespace-replaceme/goldpinger:1.1.0"
|
||||
# podIP is used to select a randomized subset of nodes to ping.
|
||||
- name: POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
image: "docker.io/bloomberg/goldpinger:2.0.0"
|
||||
imagePullPolicy: Always
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
resources:
|
||||
limits:
|
||||
memory: 80Mi
|
||||
requests:
|
||||
cpu: 1m
|
||||
memory: 40Mi
|
||||
ports:
|
||||
- containerPort: 80
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8080
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 5
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8080
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 5
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@@ -53,7 +83,7 @@ metadata:
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 80
|
||||
- port: 8080
|
||||
nodePort: 30080
|
||||
name: http
|
||||
selector:
|
||||
|
||||
@@ -5,20 +5,24 @@ metadata:
|
||||
name: goldpinger
|
||||
labels:
|
||||
app: goldpinger
|
||||
version: "1.1.0"
|
||||
version: "2.0.0"
|
||||
spec:
|
||||
updateStrategy:
|
||||
type: RollingUpdate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: goldpinger
|
||||
version: "1.1.0"
|
||||
version: "2.0.0"
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: goldpinger
|
||||
version: "1.1.0"
|
||||
version: "2.0.0"
|
||||
spec:
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
fsGroup: 2000
|
||||
# if you'd like to use a secret to inject a kubeconfig, you can do it like this
|
||||
volumes:
|
||||
- name: kubeconfig
|
||||
@@ -30,7 +34,7 @@ spec:
|
||||
- name: HOST
|
||||
value: "0.0.0.0"
|
||||
- name: PORT
|
||||
value: "80"
|
||||
value: "8080"
|
||||
# kubeconfig needs to match the location of what's injected in the secret
|
||||
# if not specified goldpinger will default to using in-cluster config
|
||||
- name: KUBECONFIG
|
||||
@@ -43,10 +47,37 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
image: "docker.io/mynamespace-replaceme/goldpinger:1.1.0"
|
||||
# podIP is used to select randomized subset of nodes to ping.
|
||||
- name: POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.podIP
|
||||
image: "docker.io/bloomberg/goldpinger:2.0.0"
|
||||
imagePullPolicy: Always
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
resources:
|
||||
limits:
|
||||
memory: 80Mi
|
||||
requests:
|
||||
cpu: 1m
|
||||
memory: 40Mi
|
||||
ports:
|
||||
- containerPort: 80
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8080
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 5
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8080
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 5
|
||||
volumeMounts:
|
||||
- mountPath: /.kube/
|
||||
name: kubeconfig
|
||||
@@ -61,7 +92,7 @@ metadata:
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 80
|
||||
- port: 8080
|
||||
nodePort: 30080
|
||||
name: http
|
||||
selector:
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"rgba(237, 129, 40, 0.89)",
|
||||
"rgba(245, 54, 54, 0.9)"
|
||||
],
|
||||
"datasource": "K8S",
|
||||
"datasource": "$datasource",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"format": "none",
|
||||
@@ -113,7 +113,7 @@
|
||||
"rgba(237, 129, 40, 0.89)",
|
||||
"rgba(245, 54, 54, 0.9)"
|
||||
],
|
||||
"datasource": "K8S",
|
||||
"datasource": "$datasource",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"format": "none",
|
||||
@@ -199,7 +199,7 @@
|
||||
"value": "avg"
|
||||
}
|
||||
],
|
||||
"datasource": "K8S",
|
||||
"datasource": "$datasource",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fontSize": "100%",
|
||||
@@ -256,7 +256,7 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "K8S",
|
||||
"datasource": "$datasource",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fill": 1,
|
||||
@@ -340,7 +340,7 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "K8S",
|
||||
"datasource": "$datasource",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fill": 1,
|
||||
@@ -436,7 +436,7 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "K8S",
|
||||
"datasource": "$datasource",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fill": 1,
|
||||
@@ -519,7 +519,7 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "K8S",
|
||||
"datasource": "$datasource",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fill": 1,
|
||||
@@ -602,7 +602,7 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "K8S",
|
||||
"datasource": "$datasource",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fill": 1,
|
||||
@@ -697,7 +697,7 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "K8S",
|
||||
"datasource": "$datasource",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fill": 1,
|
||||
@@ -781,7 +781,7 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "K8S",
|
||||
"datasource": "$datasource",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fill": 1,
|
||||
@@ -865,7 +865,7 @@
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "K8S",
|
||||
"datasource": "$datasource",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fill": 1,
|
||||
@@ -958,10 +958,25 @@
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"current": {
|
||||
"text": "prometheus",
|
||||
"value": "prometheus"
|
||||
},
|
||||
"hide": 0,
|
||||
"label": "datasource",
|
||||
"name": "datasource",
|
||||
"options": [],
|
||||
"query": "prometheus",
|
||||
"refresh": 1,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"type": "datasource"
|
||||
},
|
||||
{
|
||||
"allValue": ".*",
|
||||
"current": {},
|
||||
"datasource": "K8S",
|
||||
"datasource": "$datasource",
|
||||
"hide": 0,
|
||||
"includeAll": true,
|
||||
"label": "Instance",
|
||||
@@ -981,7 +996,7 @@
|
||||
{
|
||||
"allValue": ".*",
|
||||
"current": {},
|
||||
"datasource": "K8S",
|
||||
"datasource": "$datasource",
|
||||
"hide": 0,
|
||||
"includeAll": true,
|
||||
"label": "Call Type",
|
||||
|
||||
51
go.mod
Normal file
51
go.mod
Normal file
@@ -0,0 +1,51 @@
|
||||
module github.com/bloomberg/goldpinger
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 // indirect
|
||||
github.com/cespare/xxhash v1.1.0
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 // indirect
|
||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 // indirect
|
||||
github.com/go-openapi/analysis v0.17.2 // indirect
|
||||
github.com/go-openapi/errors v0.17.2
|
||||
github.com/go-openapi/jsonpointer v0.17.2 // indirect
|
||||
github.com/go-openapi/jsonreference v0.17.2 // indirect
|
||||
github.com/go-openapi/loads v0.17.2
|
||||
github.com/go-openapi/runtime v0.17.2
|
||||
github.com/go-openapi/spec v0.17.2
|
||||
github.com/go-openapi/strfmt v0.17.2
|
||||
github.com/go-openapi/swag v0.17.2
|
||||
github.com/go-openapi/validate v0.17.2
|
||||
github.com/gogo/protobuf v0.0.0-20170330071051-c0656edd0d9e // indirect
|
||||
github.com/golang/glog v0.0.0-20141105023935-44145f04b68c // indirect
|
||||
github.com/google/btree v1.0.0 // indirect
|
||||
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367 // indirect
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7 // indirect
|
||||
github.com/imdario/mergo v0.3.5 // indirect
|
||||
github.com/jessevdk/go-flags v1.4.0
|
||||
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/prometheus/client_golang v0.9.1
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 // indirect
|
||||
github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39 // indirect
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d // indirect
|
||||
github.com/spf13/pflag v1.0.1 // indirect
|
||||
github.com/stuartnelson3/go-rendezvous v0.2.0
|
||||
golang.org/x/crypto v0.0.0-20180808211826-de0752318171 // indirect
|
||||
golang.org/x/image v0.0.0-20190220214146-31aff87c08e9
|
||||
golang.org/x/net v0.0.0-20181106065722-10aee1819953
|
||||
golang.org/x/oauth2 v0.0.0-20170412232759-a6bd8cefa181 // indirect
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a // indirect
|
||||
golang.org/x/sys v0.0.0-20181106073832-7155702f2d47 // indirect
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d // indirect
|
||||
google.golang.org/appengine v1.3.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.0 // indirect
|
||||
k8s.io/api v0.0.0-20181004124137-fd83cbc87e76 // indirect
|
||||
k8s.io/apimachinery v0.0.0-20180913025736-6dd46049f395
|
||||
k8s.io/client-go v9.0.0+incompatible
|
||||
)
|
||||
138
go.sum
Normal file
138
go.sum
Normal file
@@ -0,0 +1,138 @@
|
||||
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf h1:eg0MeVzsP1G42dRafH3vf+al2vQIJU0YHX+1Tw87oco=
|
||||
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
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/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk=
|
||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 h1:ZktWZesgun21uEDrwW7iEV1zPCGQldM2atlJZ3TdvVM=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 h1:DujepqpGd1hyOd7aW59XpK7Qymp8iy83xq74fLr21is=
|
||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
|
||||
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||
github.com/go-openapi/analysis v0.17.2 h1:eYp14J1o8TTSCzndHBtsNuckikV1PfZOSnx4BcBeu0c=
|
||||
github.com/go-openapi/analysis v0.17.2/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||
github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
|
||||
github.com/go-openapi/errors v0.17.2 h1:azEQ8Fnx0jmtFF2fxsnmd6I0x6rsweUF63qqSO1NmKk=
|
||||
github.com/go-openapi/errors v0.17.2/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
|
||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.17.2 h1:3ekBy41gar/iJi2KSh/au/PrC2vpLr85upF/UZmm3W0=
|
||||
github.com/go-openapi/jsonpointer v0.17.2/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.17.2 h1:lF3z7AH8dd0IKXc1zEBi1dj0B4XgVb5cVjn39dCK3Ls=
|
||||
github.com/go-openapi/jsonreference v0.17.2/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||
github.com/go-openapi/loads v0.17.2 h1:tEXYu6Xc0pevpzzQx5ghrMN9F7IVpN/+u4iD3rkYE5o=
|
||||
github.com/go-openapi/loads v0.17.2/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
|
||||
github.com/go-openapi/runtime v0.17.2 h1:/ZK67ikFhQAMFFH/aPu2MaGH7QjP4wHBvHYOVIzDAw0=
|
||||
github.com/go-openapi/runtime v0.17.2/go.mod h1:QO936ZXeisByFmZEO1IS1Dqhtf4QV1sYYFtIq6Ld86Q=
|
||||
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.17.2 h1:eb2NbuCnoe8cWAxhtK6CfMWUYmiFEZJ9Hx3Z2WRwJ5M=
|
||||
github.com/go-openapi/spec v0.17.2/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||
github.com/go-openapi/strfmt v0.17.2 h1:2KDns36DMHXG9/iYkOjiX+/8fKK9GCU5ELZ+J6qcRVA=
|
||||
github.com/go-openapi/strfmt v0.17.2/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.17.2 h1:K/ycE/XTUDFltNHSO32cGRUhrVGJD64o8WgAIZNyc3k=
|
||||
github.com/go-openapi/swag v0.17.2/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/validate v0.17.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
||||
github.com/go-openapi/validate v0.17.2 h1:lwFfiS4sv5DvOrsYDsYq4N7UU8ghXiYtPJ+VcQnC3Xg=
|
||||
github.com/go-openapi/validate v0.17.2/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
||||
github.com/gogo/protobuf v0.0.0-20170330071051-c0656edd0d9e h1:ago6fNuQ6IhszPsXkeU7qRCyfsIX7L67WDybsAPkLl8=
|
||||
github.com/gogo/protobuf v0.0.0-20170330071051-c0656edd0d9e/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/glog v0.0.0-20141105023935-44145f04b68c h1:CbdkBQ1/PiAo0FYJhQGwASD8wrgNvTdf01g6+O9tNuA=
|
||||
github.com/golang/glog v0.0.0-20141105023935-44145f04b68c/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367 h1:ScAXWS+TR6MZKex+7Z8rneuSJH+FSDqd6ocQyl+ZHo4=
|
||||
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7 h1:6TSoaYExHper8PYsJu23GWVNOyYRCSnIFyxKgLSZ54w=
|
||||
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3 h1:/UewZcckqhvnnS0C6r3Sher2hSEbVmM6Ogpcjen08+Y=
|
||||
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
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/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
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/prometheus/client_golang v0.9.1 h1:K47Rk0v/fkEfwfQet2KWhscE0cJzjgCCDBG2KHZoVno=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39 h1:Cto4X6SVMWRPBkJ/3YHn1iDGDGc/Z+sW+AEMKHMVvN4=
|
||||
github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d h1:GoAlyOgbOEIFdaDqxJVlbOQ1DtGmZWs/Qau0hIlk+WQ=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stuartnelson3/go-rendezvous v0.2.0 h1:H5IexrsptBzCMQEjTRrNH20MVXGqpFf1JUCPglaxd6I=
|
||||
github.com/stuartnelson3/go-rendezvous v0.2.0/go.mod h1:njfgP6zISyRnZ3iQN13NSEILfSNLN4ysxBoGxHs5PJ0=
|
||||
golang.org/x/crypto v0.0.0-20180808211826-de0752318171 h1:vYogbvSFj2YXcjQxFHu/rASSOt9sLytpCaSkiwQ135I=
|
||||
golang.org/x/crypto v0.0.0-20180808211826-de0752318171/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/image v0.0.0-20190220214146-31aff87c08e9 h1:+vH8qNweCrORN49012OX3h0oWEXO3p+rRnpAGQinddk=
|
||||
golang.org/x/image v0.0.0-20190220214146-31aff87c08e9/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181106065722-10aee1819953 h1:LuZIitY8waaxUfNIdtajyE/YzA/zyf0YxXG27VpLrkg=
|
||||
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/oauth2 v0.0.0-20170412232759-a6bd8cefa181 h1:/4OaQ4bC66Oq9JDhUnxTjBGt8XBhDuwgMRXHgvfcCUY=
|
||||
golang.org/x/oauth2 v0.0.0-20170412232759-a6bd8cefa181/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20181106073832-7155702f2d47 h1:jpuvBuBQe3SontqHcH6FOLtHI+yUQ3d75Q9t38Bxp0w=
|
||||
golang.org/x/sys v0.0.0-20181106073832-7155702f2d47/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d h1:TnM+PKb3ylGmZvyPXmo9m/wktg7Jn/a/fNmr33HSj8g=
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/inf.v0 v0.9.0 h1:3zYtXIO92bvsdS3ggAdA8Gb4Azj0YU+TVY1uGYNFA8o=
|
||||
gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
k8s.io/api v0.0.0-20181004124137-fd83cbc87e76 h1:cGc6jt7tNK7a2WfgNKjxjoU/UXXr9Q7JTqvCupZ+6+Y=
|
||||
k8s.io/api v0.0.0-20181004124137-fd83cbc87e76/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
|
||||
k8s.io/apimachinery v0.0.0-20180913025736-6dd46049f395 h1:X+c9tYTDc9Pmt+Z1YSMqmUTCYf13VYe1u+ZwzjgpK0M=
|
||||
k8s.io/apimachinery v0.0.0-20180913025736-6dd46049f395/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
|
||||
k8s.io/client-go v9.0.0+incompatible h1:2kqW3X2xQ9SbFvWZjGEHBLlWc1LG9JIJNXWkuqwdZ3A=
|
||||
k8s.io/client-go v9.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
|
||||
@@ -47,7 +47,7 @@ func NewCheckServicePodsOK() *CheckServicePodsOK {
|
||||
Success, return response
|
||||
*/
|
||||
type CheckServicePodsOK struct {
|
||||
Payload models.CheckResults
|
||||
Payload *models.CheckResults
|
||||
}
|
||||
|
||||
func (o *CheckServicePodsOK) Error() string {
|
||||
@@ -56,8 +56,10 @@ func (o *CheckServicePodsOK) Error() string {
|
||||
|
||||
func (o *CheckServicePodsOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
|
||||
|
||||
o.Payload = new(models.CheckResults)
|
||||
|
||||
// response payload
|
||||
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
package goldpinger
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -27,14 +29,14 @@ import (
|
||||
|
||||
// CheckNeighbours queries the kubernetes API server for all other goldpinger pods
|
||||
// then calls Ping() on each one
|
||||
func CheckNeighbours() models.CheckResults {
|
||||
return PingAllPods(GetAllPods())
|
||||
func CheckNeighbours(ps *PodSelecter) *models.CheckResults {
|
||||
return PingAllPods(ps.SelectPods())
|
||||
}
|
||||
|
||||
// CheckNeighboursNeighbours queries the kubernetes API server for all other goldpinger
|
||||
// pods then calls Check() on each one
|
||||
func CheckNeighboursNeighbours() *models.CheckAllResults {
|
||||
return CheckAllPods(GetAllPods())
|
||||
func CheckNeighboursNeighbours(ps *PodSelecter) *models.CheckAllResults {
|
||||
return CheckAllPods(ps.SelectPods())
|
||||
}
|
||||
|
||||
type PingAllPodsResult struct {
|
||||
@@ -50,7 +52,25 @@ func pickPodHostIP(podIP, hostIP string) string {
|
||||
return podIP
|
||||
}
|
||||
|
||||
func PingAllPods(pods map[string]string) models.CheckResults {
|
||||
func checkDNS() *models.DNSResults {
|
||||
results := models.DNSResults{}
|
||||
for _, host := range GoldpingerConfig.DnsHosts {
|
||||
|
||||
var dnsResult models.DNSResult
|
||||
|
||||
start := time.Now()
|
||||
_, err := net.LookupIP(host)
|
||||
if err != nil {
|
||||
dnsResult.Error = err.Error()
|
||||
CountDnsError(host)
|
||||
}
|
||||
dnsResult.ResponseTimeMs = time.Since(start).Nanoseconds() / int64(time.Millisecond)
|
||||
results[host] = dnsResult
|
||||
}
|
||||
return &results
|
||||
}
|
||||
|
||||
func PingAllPods(pods map[string]string) *models.CheckResults {
|
||||
|
||||
result := models.CheckResults{}
|
||||
|
||||
@@ -61,34 +81,51 @@ func PingAllPods(pods map[string]string) models.CheckResults {
|
||||
for podIP, hostIP := range pods {
|
||||
|
||||
go func(podIP string, hostIP string) {
|
||||
var channelResult PingAllPodsResult
|
||||
|
||||
// metrics
|
||||
CountCall("made", "ping")
|
||||
timer := GetLabeledPeersCallsTimer("ping", hostIP, podIP)
|
||||
start := time.Now()
|
||||
resp, err := getClient(pickPodHostIP(podIP, hostIP)).Operations.Ping(nil)
|
||||
|
||||
// setup
|
||||
var channelResult PingAllPodsResult
|
||||
channelResult.hostIPv4.UnmarshalText([]byte(hostIP))
|
||||
var OK = (err == nil)
|
||||
if OK {
|
||||
responseTime := time.Since(start).Nanoseconds() / int64(time.Millisecond)
|
||||
channelResult.podResult = models.PodResult{HostIP: channelResult.hostIPv4, OK: &OK, Response: resp.Payload, StatusCode: 200, ResponseTimeMs: responseTime}
|
||||
timer.ObserveDuration()
|
||||
} else {
|
||||
channelResult.podResult = models.PodResult{HostIP: channelResult.hostIPv4, OK: &OK, Error: err.Error(), StatusCode: 500}
|
||||
CountError("ping")
|
||||
}
|
||||
channelResult.podIP = podIP
|
||||
|
||||
OK := false
|
||||
var responseTime int64
|
||||
client, err := getClient(pickPodHostIP(podIP, hostIP))
|
||||
|
||||
if err != nil {
|
||||
channelResult.podResult = models.PodResult{HostIP: channelResult.hostIPv4, OK: &OK, Error: err.Error(), StatusCode: 500, ResponseTimeMs: responseTime}
|
||||
channelResult.podIP = hostIP
|
||||
CountError("ping")
|
||||
} else {
|
||||
resp, err := client.Operations.Ping(nil)
|
||||
responseTime = time.Since(start).Nanoseconds() / int64(time.Millisecond)
|
||||
OK = (err == nil)
|
||||
if OK {
|
||||
channelResult.podResult = models.PodResult{HostIP: channelResult.hostIPv4, OK: &OK, Response: resp.Payload, StatusCode: 200, ResponseTimeMs: responseTime}
|
||||
timer.ObserveDuration()
|
||||
} else {
|
||||
channelResult.podResult = models.PodResult{HostIP: channelResult.hostIPv4, OK: &OK, Error: err.Error(), StatusCode: 504, ResponseTimeMs: responseTime}
|
||||
CountError("ping")
|
||||
}
|
||||
}
|
||||
|
||||
ch <- channelResult
|
||||
wg.Done()
|
||||
}(podIP, hostIP)
|
||||
}
|
||||
if len(GoldpingerConfig.DnsHosts) > 0 {
|
||||
result.DNSResults = *checkDNS()
|
||||
}
|
||||
wg.Wait()
|
||||
close(ch)
|
||||
|
||||
counterHealthy, counterUnhealthy := 0.0, 0.0
|
||||
|
||||
result.PodResults = make(map[string]models.PodResult)
|
||||
for response := range ch {
|
||||
var podIPv4 strfmt.IPv4
|
||||
podIPv4.UnmarshalText([]byte(response.podIP))
|
||||
@@ -97,10 +134,10 @@ func PingAllPods(pods map[string]string) models.CheckResults {
|
||||
} else {
|
||||
counterUnhealthy++
|
||||
}
|
||||
result[response.podIP] = response.podResult
|
||||
result.PodResults[response.podIP] = response.podResult
|
||||
}
|
||||
CountHealthyUnhealthyNodes(counterHealthy, counterUnhealthy)
|
||||
return result
|
||||
return &result
|
||||
}
|
||||
|
||||
type CheckServicePodsResult struct {
|
||||
@@ -120,30 +157,45 @@ func CheckAllPods(pods map[string]string) *models.CheckAllResults {
|
||||
for podIP, hostIP := range pods {
|
||||
|
||||
go func(podIP string, hostIP string) {
|
||||
var channelResult CheckServicePodsResult
|
||||
|
||||
// stats
|
||||
CountCall("made", "check")
|
||||
timer := GetLabeledPeersCallsTimer("check", hostIP, podIP)
|
||||
resp, err := getClient(pickPodHostIP(podIP, hostIP)).Operations.CheckServicePods(nil)
|
||||
|
||||
// setup
|
||||
var channelResult CheckServicePodsResult
|
||||
channelResult.hostIPv4.UnmarshalText([]byte(hostIP))
|
||||
var OK = (err == nil)
|
||||
if OK {
|
||||
channelResult.checkAllPodResult = models.CheckAllPodResult{
|
||||
OK: &OK,
|
||||
HostIP: channelResult.hostIPv4,
|
||||
Response: resp.Payload,
|
||||
}
|
||||
timer.ObserveDuration()
|
||||
} else {
|
||||
channelResult.podIP = podIP
|
||||
client, err := getClient(pickPodHostIP(podIP, hostIP))
|
||||
OK := false
|
||||
|
||||
if err != nil {
|
||||
channelResult.checkAllPodResult = models.CheckAllPodResult{
|
||||
OK: &OK,
|
||||
HostIP: channelResult.hostIPv4,
|
||||
Error: err.Error(),
|
||||
}
|
||||
channelResult.podIP = hostIP
|
||||
CountError("checkAll")
|
||||
} else {
|
||||
resp, err := client.Operations.CheckServicePods(nil)
|
||||
OK = (err == nil)
|
||||
if OK {
|
||||
channelResult.checkAllPodResult = models.CheckAllPodResult{
|
||||
OK: &OK,
|
||||
HostIP: channelResult.hostIPv4,
|
||||
Response: resp.Payload,
|
||||
}
|
||||
timer.ObserveDuration()
|
||||
} else {
|
||||
channelResult.checkAllPodResult = models.CheckAllPodResult{
|
||||
OK: &OK,
|
||||
HostIP: channelResult.hostIPv4,
|
||||
Error: err.Error(),
|
||||
}
|
||||
CountError("checkAll")
|
||||
}
|
||||
}
|
||||
channelResult.podIP = podIP
|
||||
|
||||
ch <- channelResult
|
||||
wg.Done()
|
||||
@@ -161,6 +213,18 @@ func CheckAllPods(pods map[string]string) *models.CheckAllResults {
|
||||
HostIP: response.hostIPv4,
|
||||
PodIP: podIPv4,
|
||||
})
|
||||
if response.checkAllPodResult.Response != nil &&
|
||||
response.checkAllPodResult.Response.DNSResults != nil {
|
||||
if result.DNSResults == nil {
|
||||
result.DNSResults = make(map[string]models.DNSResults)
|
||||
}
|
||||
for host := range response.checkAllPodResult.Response.DNSResults {
|
||||
if result.DNSResults[host] == nil {
|
||||
result.DNSResults[host] = make(map[string]models.DNSResult)
|
||||
}
|
||||
result.DNSResults[host][response.podIP] = response.checkAllPodResult.Response.DNSResults[host]
|
||||
}
|
||||
}
|
||||
}
|
||||
return &result
|
||||
}
|
||||
@@ -176,11 +240,14 @@ func HealthCheck() *models.HealthCheckResults {
|
||||
return &result
|
||||
}
|
||||
|
||||
func getClient(hostIP string) *apiclient.Goldpinger {
|
||||
func getClient(hostIP string) (*apiclient.Goldpinger, error) {
|
||||
if hostIP == "" {
|
||||
return nil, errors.New("Host or pod IP empty, can't make a call")
|
||||
}
|
||||
host := fmt.Sprintf("%s:%d", hostIP, GoldpingerConfig.Port)
|
||||
transport := httptransport.New(host, "", nil)
|
||||
client := apiclient.New(transport, strfmt.Default)
|
||||
apiclient.Default.SetTransport(transport)
|
||||
|
||||
return client
|
||||
return client, nil
|
||||
}
|
||||
|
||||
@@ -24,8 +24,13 @@ var GoldpingerConfig = struct {
|
||||
KubeConfigPath string `long:"kubeconfig" description:"Path to kubeconfig file" env:"KUBECONFIG"`
|
||||
RefreshInterval int `long:"refresh-interval" description:"If > 0, will create a thread and collect stats every n seconds" env:"REFRESH_INTERVAL" default:"30"`
|
||||
Hostname string `long:"hostname" description:"Hostname to use" env:"HOSTNAME"`
|
||||
PodIP string `long:"pod-ip" description:"Pod IP to use" env:"POD_IP"`
|
||||
PingNumber uint `long:"ping-number" description:"Number of peers to ping. A value of 0 indicates all peers should be pinged." default:"0" env:"PING_NUMBER"`
|
||||
Port int `long:"client-port-override" description:"(for testing) use this port when calling other instances" env:"CLIENT_PORT_OVERRIDE"`
|
||||
UseHostIP bool `long:"use-host-ip" description:"When making the calls, use host ip (defaults to pod ip)" env:"USE_HOST_IP"`
|
||||
LabelSelector string `long:"label-selector" description:"label selector to use to discover goldpinger pods in the cluster" env:"LABEL_SELECTOR" default:"app=goldpinger"`
|
||||
KubernetesClient *kubernetes.Clientset
|
||||
*PodSelecter
|
||||
|
||||
DnsHosts []string `long:"host-to-resolve" description:"A host to attempt dns resolve on (space delimited)" env:"HOSTS_TO_RESOLVE" env-delim:" "`
|
||||
}{}
|
||||
|
||||
146
pkg/goldpinger/heatmap.go
Normal file
146
pkg/goldpinger/heatmap.go
Normal file
@@ -0,0 +1,146 @@
|
||||
// Copyright 2018 Bloomberg Finance L.P.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// This file is safe to edit. Once it exists it will not be overwritten
|
||||
|
||||
package goldpinger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"log"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/image/font"
|
||||
"golang.org/x/image/font/basicfont"
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
||||
func addLabel(img *image.RGBA, x, y int, text string) {
|
||||
drawer := &font.Drawer{
|
||||
Dst: img,
|
||||
Src: image.NewUniform(color.RGBA{25, 200, 25, 255}),
|
||||
Face: basicfont.Face7x13,
|
||||
Dot: fixed.Point26_6{fixed.Int26_6(x * 64), fixed.Int26_6(y * 64)},
|
||||
}
|
||||
drawer.DrawString(text)
|
||||
}
|
||||
|
||||
// Calculates the color of the box to draw based on the latency and tresholds
|
||||
// We are aiming at slightly more palatable colors than just moving from 255 green to 255 red,
|
||||
// so we will use 25B, and then move from (25R, 200G) to (200R, 25G), so our scale is effectively 350 points
|
||||
func getPingBoxColor(latency int64, tresholdLatencies [3]int64) *color.RGBA {
|
||||
var red, green uint8 = 25, 200
|
||||
if latency > tresholdLatencies[2] {
|
||||
red, green = 200, 25
|
||||
} else if latency >= tresholdLatencies[1] {
|
||||
red, green = 200, 200
|
||||
diff := (float32(latency-tresholdLatencies[1]) / float32(tresholdLatencies[2]-tresholdLatencies[1])) * 175
|
||||
green = green - uint8(diff)
|
||||
} else if latency >= tresholdLatencies[0] {
|
||||
red, green = 25, 200
|
||||
diff := (float32(latency-tresholdLatencies[0]) / float32(tresholdLatencies[1]-tresholdLatencies[0])) * 175
|
||||
red = red + uint8(diff)
|
||||
}
|
||||
return &color.RGBA{red, green, 25, 255}
|
||||
}
|
||||
|
||||
func drawPingBox(img *image.RGBA, _x, _y, size int, color *color.RGBA) {
|
||||
for x := _x; x < _x+size; x++ {
|
||||
for y := _y; y < _y+size; y++ {
|
||||
img.Set(x, y, *color)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getPingBoxCoordinates(col, row, boxSize, padding int) (int, int) {
|
||||
return col * (boxSize + padding), row * (boxSize + padding)
|
||||
}
|
||||
|
||||
// HeatmapHandler returns a PNG with a heatmap representation
|
||||
func HeatmapHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// parse the query to set the parameters
|
||||
query := r.URL.Query()
|
||||
|
||||
// get the results
|
||||
checkResults := CheckAllPods(GetAllPods())
|
||||
|
||||
// set some sizes
|
||||
numberOfPods := len(checkResults.Responses)
|
||||
legendSize := 200
|
||||
boxSize := 14
|
||||
paddingSize := 1
|
||||
heatmapSize := numberOfPods*(boxSize+paddingSize) + boxSize*2
|
||||
tresholdLatencies := [3]int64{1, 10, 100}
|
||||
for index := range tresholdLatencies {
|
||||
stringValue := query["t"+fmt.Sprintf("%d", index)]
|
||||
if len(stringValue) == 0 {
|
||||
continue
|
||||
}
|
||||
if v, err := strconv.ParseInt(stringValue[0], 0, 64); err == nil && v >= 0 {
|
||||
tresholdLatencies[index] = v
|
||||
}
|
||||
}
|
||||
|
||||
canvas := image.NewRGBA(image.Rect(0, 0, heatmapSize+legendSize, heatmapSize))
|
||||
|
||||
// establish an order and fix the max delay
|
||||
var keys []string
|
||||
for sourceIP := range checkResults.Responses {
|
||||
keys = append(keys, sourceIP)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
order := make(map[string]int)
|
||||
for index, key := range keys {
|
||||
order[key] = index
|
||||
}
|
||||
|
||||
// draw all the boxes
|
||||
for sourceIP, results := range checkResults.Responses {
|
||||
if *results.OK {
|
||||
for destinationIP, response := range results.Response.PodResults {
|
||||
x, y := getPingBoxCoordinates(order[sourceIP], order[destinationIP], boxSize, paddingSize)
|
||||
color := getPingBoxColor(response.ResponseTimeMs, tresholdLatencies)
|
||||
drawPingBox(canvas, boxSize+x, boxSize+y, boxSize, color)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// draw the legend
|
||||
for index, ip := range keys {
|
||||
// ip
|
||||
addLabel(canvas, heatmapSize, (index+1)*(boxSize+paddingSize)+13, fmt.Sprintf("%d", index)+": "+ip)
|
||||
// rows
|
||||
addLabel(canvas, 0, (index+1)*(boxSize+paddingSize)+13, fmt.Sprintf("%d", index))
|
||||
// columns
|
||||
addLabel(canvas, (index+1)*(boxSize+paddingSize), 13, fmt.Sprintf("%d", index))
|
||||
}
|
||||
|
||||
buffer := new(bytes.Buffer)
|
||||
if err := png.Encode(buffer, canvas); err != nil {
|
||||
log.Println("error encoding png", err)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "image/png")
|
||||
w.Header().Set("Content-Length", strconv.Itoa(len(buffer.Bytes())))
|
||||
if _, err := w.Write(buffer.Bytes()); err != nil {
|
||||
log.Println("error writing heatmap buffer out", err)
|
||||
}
|
||||
}
|
||||
61
pkg/goldpinger/pod_selecter.go
Normal file
61
pkg/goldpinger/pod_selecter.go
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright 2018 Bloomberg Finance L.P.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package goldpinger
|
||||
|
||||
import (
|
||||
"github.com/cespare/xxhash"
|
||||
rendezvous "github.com/stuartnelson3/go-rendezvous"
|
||||
)
|
||||
|
||||
// PodSelecter selects the result of getPods() down to count instances
|
||||
// according to a rendezvous hash.
|
||||
type PodSelecter struct {
|
||||
count uint
|
||||
podIP string
|
||||
getPods func() map[string]string
|
||||
}
|
||||
|
||||
// NewPodSelecter creates a new PodSelecter struct.
|
||||
func NewPodSelecter(count uint, podIP string, getPods func() map[string]string) *PodSelecter {
|
||||
if podIP == "" {
|
||||
// If podIP is blank, then we can't use the rendezvous hash to
|
||||
// assign the IP correctly. Setting count=0 will force all pods
|
||||
// to be pinged.
|
||||
count = 0
|
||||
}
|
||||
return &PodSelecter{
|
||||
count: count,
|
||||
podIP: podIP,
|
||||
getPods: getPods,
|
||||
}
|
||||
}
|
||||
|
||||
// SelectPods returns a map of pods filtered according to its configuration.
|
||||
func (p *PodSelecter) SelectPods() map[string]string {
|
||||
allPods := p.getPods()
|
||||
if p.count == 0 || p.count >= uint(len(allPods)) {
|
||||
return allPods
|
||||
}
|
||||
rzv := rendezvous.New([]string{}, rendezvous.Hasher(xxhash.Sum64String))
|
||||
for podIP := range allPods {
|
||||
rzv.Add(podIP)
|
||||
}
|
||||
matches := rzv.LookupN(p.podIP, p.count)
|
||||
toPing := make(map[string]string)
|
||||
for _, podIP := range matches {
|
||||
toPing[podIP] = allPods[podIP]
|
||||
}
|
||||
return toPing
|
||||
}
|
||||
@@ -82,6 +82,16 @@ var (
|
||||
"type",
|
||||
},
|
||||
)
|
||||
goldpingerDnsErrorsCounter = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "goldpinger_dns_errors_total",
|
||||
Help: "Statistics of DNS errors per instance",
|
||||
},
|
||||
[]string{
|
||||
"goldpinger_instance",
|
||||
"host",
|
||||
},
|
||||
)
|
||||
|
||||
bootTime = time.Now()
|
||||
)
|
||||
@@ -92,6 +102,7 @@ func init() {
|
||||
prometheus.MustRegister(goldpingerResponseTimePeersHistogram)
|
||||
prometheus.MustRegister(goldpingerResponseTimeKubernetesHistogram)
|
||||
prometheus.MustRegister(goldpingerErrorsCounter)
|
||||
prometheus.MustRegister(goldpingerDnsErrorsCounter)
|
||||
log.Println("Metrics setup - see /metrics")
|
||||
}
|
||||
|
||||
@@ -131,6 +142,14 @@ func CountError(errorType string) {
|
||||
).Inc()
|
||||
}
|
||||
|
||||
// counts instances of dns errors
|
||||
func CountDnsError(host string) {
|
||||
goldpingerDnsErrorsCounter.WithLabelValues(
|
||||
GoldpingerConfig.Hostname,
|
||||
host,
|
||||
).Inc()
|
||||
}
|
||||
|
||||
// returns a timer for easy observing of the durations of calls to kubernetes API
|
||||
func GetLabeledKubernetesCallsTimer() *prometheus.Timer {
|
||||
return prometheus.NewTimer(
|
||||
|
||||
@@ -21,17 +21,17 @@ import (
|
||||
)
|
||||
|
||||
func StartUpdater() {
|
||||
|
||||
if GoldpingerConfig.RefreshInterval <= 0 {
|
||||
log.Println("Not creating updater, period is 0")
|
||||
return
|
||||
}
|
||||
|
||||
// start the updater
|
||||
go func() {
|
||||
for {
|
||||
results := PingAllPods(GetAllPods())
|
||||
results := PingAllPods(GoldpingerConfig.PodSelecter.SelectPods())
|
||||
var troublemakers []string
|
||||
for podIP, value := range results {
|
||||
for podIP, value := range results.PodResults {
|
||||
if *value.OK != true {
|
||||
troublemakers = append(troublemakers, fmt.Sprintf("%s (%s)", podIP, value.HostIP.String()))
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ type CheckAllPodResult struct {
|
||||
Error string `json:"error,omitempty"`
|
||||
|
||||
// response
|
||||
Response CheckResults `json:"response,omitempty"`
|
||||
Response *CheckResults `json:"response,omitempty"`
|
||||
|
||||
// status code
|
||||
StatusCode int32 `json:"status-code,omitempty"`
|
||||
@@ -71,11 +71,13 @@ func (m *CheckAllPodResult) validateResponse(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.Response.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("response")
|
||||
if m.Response != nil {
|
||||
if err := m.Response.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("response")
|
||||
}
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -22,6 +22,9 @@ type CheckAllResults struct {
|
||||
// o k
|
||||
OK *bool `json:"OK,omitempty"`
|
||||
|
||||
// dns results
|
||||
DNSResults map[string]DNSResults `json:"dnsResults,omitempty"`
|
||||
|
||||
// hosts
|
||||
Hosts []*CheckAllResultsHostsItems0 `json:"hosts"`
|
||||
|
||||
@@ -39,6 +42,10 @@ type CheckAllResults struct {
|
||||
func (m *CheckAllResults) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateDNSResults(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateHosts(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
@@ -53,6 +60,25 @@ func (m *CheckAllResults) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CheckAllResults) validateDNSResults(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.DNSResults) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for k := range m.DNSResults {
|
||||
|
||||
if val, ok := m.DNSResults[k]; ok {
|
||||
if err := val.Validate(formats); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CheckAllResults) validateHosts(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.Hosts) { // not required
|
||||
|
||||
@@ -9,28 +9,31 @@ import (
|
||||
strfmt "github.com/go-openapi/strfmt"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
// CheckResults check results
|
||||
// swagger:model CheckResults
|
||||
type CheckResults map[string]PodResult
|
||||
type CheckResults struct {
|
||||
|
||||
// dns results
|
||||
DNSResults DNSResults `json:"dnsResults,omitempty"`
|
||||
|
||||
// pod results
|
||||
PodResults map[string]PodResult `json:"podResults,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this check results
|
||||
func (m CheckResults) Validate(formats strfmt.Registry) error {
|
||||
func (m *CheckResults) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
for k := range m {
|
||||
|
||||
if err := validate.Required(k, "body", m[k]); err != nil {
|
||||
return err
|
||||
}
|
||||
if val, ok := m[k]; ok {
|
||||
if err := val.Validate(formats); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := m.validateDNSResults(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validatePodResults(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
@@ -38,3 +41,59 @@ func (m CheckResults) Validate(formats strfmt.Registry) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CheckResults) validateDNSResults(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.DNSResults) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.DNSResults.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("dnsResults")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *CheckResults) validatePodResults(formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.PodResults) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for k := range m.PodResults {
|
||||
|
||||
if err := validate.Required("podResults"+"."+k, "body", m.PodResults[k]); err != nil {
|
||||
return err
|
||||
}
|
||||
if val, ok := m.PodResults[k]; ok {
|
||||
if err := val.Validate(formats); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *CheckResults) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *CheckResults) UnmarshalBinary(b []byte) error {
|
||||
var res CheckResults
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
|
||||
46
pkg/models/dns_result.go
Normal file
46
pkg/models/dns_result.go
Normal file
@@ -0,0 +1,46 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
strfmt "github.com/go-openapi/strfmt"
|
||||
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// DNSResult Dns result
|
||||
// swagger:model DnsResult
|
||||
type DNSResult struct {
|
||||
|
||||
// error
|
||||
Error string `json:"error,omitempty"`
|
||||
|
||||
// response time ms
|
||||
ResponseTimeMs int64 `json:"response-time-ms,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this Dns result
|
||||
func (m *DNSResult) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *DNSResult) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *DNSResult) UnmarshalBinary(b []byte) error {
|
||||
var res DNSResult
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
40
pkg/models/dns_results.go
Normal file
40
pkg/models/dns_results.go
Normal file
@@ -0,0 +1,40 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
strfmt "github.com/go-openapi/strfmt"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
// DNSResults Dns results
|
||||
// swagger:model DnsResults
|
||||
type DNSResults map[string]DNSResult
|
||||
|
||||
// Validate validates this Dns results
|
||||
func (m DNSResults) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
for k := range m {
|
||||
|
||||
if err := validate.Required(k, "body", m[k]); err != nil {
|
||||
return err
|
||||
}
|
||||
if val, ok := m[k]; ok {
|
||||
if err := val.Validate(formats); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -47,6 +47,7 @@ func configureFlags(api *operations.GoldpingerAPI) {
|
||||
|
||||
func configureAPI(api *operations.GoldpingerAPI) http.Handler {
|
||||
// configure the api here
|
||||
ps := goldpinger.GoldpingerConfig.PodSelecter
|
||||
api.ServeError = errors.ServeError
|
||||
|
||||
api.JSONConsumer = runtime.JSONConsumer()
|
||||
@@ -61,13 +62,13 @@ func configureAPI(api *operations.GoldpingerAPI) http.Handler {
|
||||
api.CheckServicePodsHandler = operations.CheckServicePodsHandlerFunc(
|
||||
func(params operations.CheckServicePodsParams) middleware.Responder {
|
||||
goldpinger.CountCall("received", "check")
|
||||
return operations.NewCheckServicePodsOK().WithPayload(goldpinger.CheckNeighbours())
|
||||
return operations.NewCheckServicePodsOK().WithPayload(goldpinger.CheckNeighbours(ps))
|
||||
})
|
||||
|
||||
api.CheckAllPodsHandler = operations.CheckAllPodsHandlerFunc(
|
||||
func(params operations.CheckAllPodsParams) middleware.Responder {
|
||||
goldpinger.CountCall("received", "check_all")
|
||||
return operations.NewCheckAllPodsOK().WithPayload(goldpinger.CheckNeighboursNeighbours())
|
||||
return operations.NewCheckAllPodsOK().WithPayload(goldpinger.CheckNeighboursNeighbours(ps))
|
||||
})
|
||||
|
||||
api.HealthzHandler = operations.HealthzHandlerFunc(
|
||||
@@ -110,6 +111,8 @@ func fileServerMiddleware(next http.Handler) http.Handler {
|
||||
fileServer := http.FileServer(http.Dir(goldpinger.GoldpingerConfig.StaticFilePath))
|
||||
if r.URL.Path == "/" {
|
||||
http.StripPrefix("/", fileServer).ServeHTTP(w, r)
|
||||
} else if r.URL.Path == "/heatmap.png" {
|
||||
goldpinger.HeatmapHandler(w, r)
|
||||
} else if strings.HasPrefix(r.URL.Path, "/static/") {
|
||||
http.StripPrefix("/static/", fileServer).ServeHTTP(w, r)
|
||||
} else {
|
||||
|
||||
@@ -7,7 +7,7 @@ Package restapi Goldpinger
|
||||
http
|
||||
Host: localhost
|
||||
BasePath: /
|
||||
Version: 1.0.0
|
||||
Version: 2.0.0
|
||||
|
||||
Consumes:
|
||||
- application/json
|
||||
|
||||
@@ -21,7 +21,7 @@ func init() {
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "Goldpinger",
|
||||
"version": "1.0.0"
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"paths": {
|
||||
"/check": {
|
||||
@@ -143,6 +143,12 @@ func init() {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"dnsResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/DnsResults"
|
||||
}
|
||||
},
|
||||
"hosts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -176,9 +182,34 @@ func init() {
|
||||
}
|
||||
},
|
||||
"CheckResults": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"dnsResults": {
|
||||
"$ref": "#/definitions/DnsResults"
|
||||
},
|
||||
"podResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/PodResult"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"DnsResult": {
|
||||
"properties": {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"response-time-ms": {
|
||||
"type": "number",
|
||||
"format": "int64"
|
||||
}
|
||||
}
|
||||
},
|
||||
"DnsResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/PodResult"
|
||||
"$ref": "#/definitions/DnsResult"
|
||||
}
|
||||
},
|
||||
"HealthCheckResults": {
|
||||
@@ -244,7 +275,7 @@ func init() {
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "Goldpinger",
|
||||
"version": "1.0.0"
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"paths": {
|
||||
"/check": {
|
||||
@@ -366,6 +397,12 @@ func init() {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"dnsResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/DnsResults"
|
||||
}
|
||||
},
|
||||
"hosts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -399,9 +436,34 @@ func init() {
|
||||
}
|
||||
},
|
||||
"CheckResults": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"dnsResults": {
|
||||
"$ref": "#/definitions/DnsResults"
|
||||
},
|
||||
"podResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/PodResult"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"DnsResult": {
|
||||
"properties": {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"response-time-ms": {
|
||||
"type": "number",
|
||||
"format": "int64"
|
||||
}
|
||||
}
|
||||
},
|
||||
"DnsResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/PodResult"
|
||||
"$ref": "#/definitions/DnsResult"
|
||||
}
|
||||
},
|
||||
"HealthCheckResults": {
|
||||
|
||||
@@ -25,7 +25,7 @@ type CheckServicePodsOK struct {
|
||||
/*
|
||||
In: Body
|
||||
*/
|
||||
Payload models.CheckResults `json:"body,omitempty"`
|
||||
Payload *models.CheckResults `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewCheckServicePodsOK creates CheckServicePodsOK with default headers values
|
||||
@@ -35,13 +35,13 @@ func NewCheckServicePodsOK() *CheckServicePodsOK {
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the check service pods o k response
|
||||
func (o *CheckServicePodsOK) WithPayload(payload models.CheckResults) *CheckServicePodsOK {
|
||||
func (o *CheckServicePodsOK) WithPayload(payload *models.CheckResults) *CheckServicePodsOK {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the check service pods o k response
|
||||
func (o *CheckServicePodsOK) SetPayload(payload models.CheckResults) {
|
||||
func (o *CheckServicePodsOK) SetPayload(payload *models.CheckResults) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
@@ -49,13 +49,10 @@ func (o *CheckServicePodsOK) SetPayload(payload models.CheckResults) {
|
||||
func (o *CheckServicePodsOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||
|
||||
rw.WriteHeader(200)
|
||||
payload := o.Payload
|
||||
if payload == nil {
|
||||
// return empty map
|
||||
payload = models.CheckResults{}
|
||||
}
|
||||
|
||||
if err := producer.Produce(rw, payload); err != nil {
|
||||
panic(err) // let the recovery middleware deal with this
|
||||
if o.Payload != nil {
|
||||
payload := o.Payload
|
||||
if err := producer.Produce(rw, payload); err != nil {
|
||||
panic(err) // let the recovery middleware deal with this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,13 +65,13 @@ type GoldpingerAPI struct {
|
||||
Middleware func(middleware.Builder) http.Handler
|
||||
|
||||
// BasicAuthenticator generates a runtime.Authenticator from the supplied basic auth function.
|
||||
// It has a default implemention in the security package, however you can replace it for your particular usage.
|
||||
// It has a default implementation in the security package, however you can replace it for your particular usage.
|
||||
BasicAuthenticator func(security.UserPassAuthentication) runtime.Authenticator
|
||||
// APIKeyAuthenticator generates a runtime.Authenticator from the supplied token auth function.
|
||||
// It has a default implemention in the security package, however you can replace it for your particular usage.
|
||||
// It has a default implementation in the security package, however you can replace it for your particular usage.
|
||||
APIKeyAuthenticator func(string, string, security.TokenAuthentication) runtime.Authenticator
|
||||
// BearerAuthenticator generates a runtime.Authenticator from the supplied bearer token auth function.
|
||||
// It has a default implemention in the security package, however you can replace it for your particular usage.
|
||||
// It has a default implementation in the security package, however you can replace it for your particular usage.
|
||||
BearerAuthenticator func(string, security.ScopedTokenAuthentication) runtime.Authenticator
|
||||
|
||||
// JSONConsumer registers a consumer for a "application/json" mime type
|
||||
|
||||
@@ -87,7 +87,7 @@ type Server struct {
|
||||
TLSHost string `long:"tls-host" description:"the IP to listen on for tls, when not specified it's the same as --host" env:"TLS_HOST"`
|
||||
TLSPort int `long:"tls-port" description:"the port to listen on for secure connections, defaults to a random value" env:"TLS_PORT"`
|
||||
TLSCertificate flags.Filename `long:"tls-certificate" description:"the certificate to use for secure connections" env:"TLS_CERTIFICATE"`
|
||||
TLSCertificateKey flags.Filename `long:"tls-key" description:"the private key to use for secure conections" env:"TLS_PRIVATE_KEY"`
|
||||
TLSCertificateKey flags.Filename `long:"tls-key" description:"the private key to use for secure connections" env:"TLS_PRIVATE_KEY"`
|
||||
TLSCACertificate flags.Filename `long:"tls-ca" description:"the certificate authority file to be used with mutual tls auth" env:"TLS_CA_CERTIFICATE"`
|
||||
TLSListenLimit int `long:"tls-listen-limit" description:"limit the number of outstanding requests"`
|
||||
TLSKeepAlive time.Duration `long:"tls-keep-alive" description:"sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)"`
|
||||
|
||||
@@ -49,7 +49,7 @@ limitations under the License.
|
||||
<script type="text/javascript" src="static/sigma.js/1.1.0/plugins/sigma.renderers.parallelEdges.min.js"></script>
|
||||
<script type="text/javascript" src="static/sigma.js/1.1.0/plugins/sigma.renderers.snapshot.min.js"></script>
|
||||
<script type="text/javascript" src="static/sigma.js/1.1.0/plugins/sigma.statistics.HITS.min.js"></script>
|
||||
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<link rel="stylesheet" href="static/bootstrap/3.3.7/css/bootstrap.min.css" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="static/bootstrap/3.3.7/css/bootstrap-theme.min.css" crossorigin="anonymous">
|
||||
@@ -86,6 +86,7 @@ limitations under the License.
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="active"><a href="#">Graph</a></li>
|
||||
<li><a href="#" id="show-data">Data</a></li>
|
||||
<li><a href="#" id="show-heatmap">Heatmap</a></li>
|
||||
<li><a href="check_all" >Raw</a></li>
|
||||
<li><a href="metrics" >Metrics</a></li>
|
||||
</ul>
|
||||
@@ -106,24 +107,70 @@ limitations under the License.
|
||||
|
||||
</div>
|
||||
|
||||
<div id="modal-window-code" class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="modal-title">title</h4>
|
||||
</div>
|
||||
<div class="modal-body" id="modal-body">
|
||||
body
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
<div id="modal-window-code" class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="modal-title">title</h4>
|
||||
</div>
|
||||
<div class="modal-body" id="modal-body">
|
||||
body
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="modal-window-heatmap" class="modal fade bs-example-modal-lg" tabindex="-2" role="dialog" aria-labelledby="myLargeModalLabel">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="modal-title">Heatmap</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div id="heatmap-body" style="padding: 10px"></div>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon" style="width: 200px">Good threshold</span>
|
||||
<input id="t0" type="number" step="1" class="form-control" placeholder="2" value="2">
|
||||
<span class="input-group-addon">milliseconds</span>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon" style="width: 200px">Warning threshold</span>
|
||||
<input id="t1" type="number" step="1" class="form-control" placeholder="5" value="5">
|
||||
<span class="input-group-addon">milliseconds</span>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon" style="width: 200px">Problem threshold</span>
|
||||
<input id="t2" type="number" step="1" class="form-control" placeholder="100" value="100">
|
||||
<span class="input-group-addon">milliseconds</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-success" id="update-heatmap" type="button">refresh</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var getHeatmapUrl = function(){
|
||||
return "heatmap.png?"
|
||||
+ "t0=" + Number($("#t0").val())
|
||||
+ "&t1=" + Number($("#t1").val())
|
||||
+ "&t2=" + Number($("#t2").val())
|
||||
+ "&now=" + Date.now();
|
||||
}
|
||||
|
||||
var fetchJSON = function(url) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
console.log("calling " + url);
|
||||
@@ -172,7 +219,7 @@ var main = function(timeout){
|
||||
|
||||
loadingDialog(true);
|
||||
|
||||
fetchJSON("/check_all?timeout="+timeout)
|
||||
fetchJSON("check_all?timeout="+timeout)
|
||||
.then(function(data){
|
||||
|
||||
loadingDialog(false);
|
||||
@@ -182,6 +229,8 @@ var main = function(timeout){
|
||||
|
||||
// prepare nodes
|
||||
var nodes = [];
|
||||
var dnsCheckNodes = [];
|
||||
var podIPs = [];
|
||||
var resp = data.responses;
|
||||
for (let podIP in resp) {
|
||||
let value = resp[podIP];
|
||||
@@ -192,14 +241,14 @@ var main = function(timeout){
|
||||
"y": 0,
|
||||
_data: value,
|
||||
});
|
||||
podIPs.push(podIP);
|
||||
};
|
||||
//console.log(nodes);
|
||||
|
||||
// prepare the edges
|
||||
var edges = [];
|
||||
var resp = data.responses;
|
||||
for (let callId in resp) {
|
||||
var call = resp[callId].response;
|
||||
var call = resp[callId].response['podResults'];
|
||||
if (typeof call !== 'string'){
|
||||
for (let target in call) {
|
||||
edges.push({
|
||||
@@ -210,8 +259,61 @@ var main = function(timeout){
|
||||
};
|
||||
}
|
||||
};
|
||||
//console.log(edges);
|
||||
|
||||
console.log(edges);
|
||||
console.log(nodes);
|
||||
|
||||
// if running goldpinger with PING_NUMBER, then we need to add nodes for the edges
|
||||
// that are not reporting but are reported to
|
||||
edges.forEach(function(edge) {
|
||||
[edge.source, edge.target].forEach(function(value) {
|
||||
if (podIPs.indexOf(value) == -1){
|
||||
nodes.push({
|
||||
"label": value,
|
||||
"id": value,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
_data: {},
|
||||
});
|
||||
podIPs.push(value);
|
||||
}
|
||||
})
|
||||
})
|
||||
console.log(nodes);
|
||||
|
||||
if ('dnsResults' in data) {
|
||||
var yoffset = 0;
|
||||
for (let checkedHost in data.dnsResults) {
|
||||
let value = data.dnsResults[checkedHost];
|
||||
var allOk = true;
|
||||
for (let pod in value) {
|
||||
var podData = value[pod];
|
||||
var elapsed = 0;
|
||||
if ('response-time-ms' in podData) {
|
||||
elapsed = podData['response-time-ms'];
|
||||
}
|
||||
var podOk = (!('error' in podData));
|
||||
allOk = allOk && podOk
|
||||
edges.push({
|
||||
source: pod,
|
||||
target: checkedHost,
|
||||
_data: {
|
||||
"OK": podOk,
|
||||
"elapsed": elapsed,
|
||||
"isDNSCheckNode": true,
|
||||
}
|
||||
});
|
||||
}
|
||||
value["OK"] = allOk
|
||||
dnsCheckNodes.push({
|
||||
"label": checkedHost,
|
||||
"id": checkedHost,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
_data: value,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// build the actual graph
|
||||
s = new sigma({
|
||||
@@ -244,6 +346,19 @@ var main = function(timeout){
|
||||
s.graph.addNode(node);
|
||||
});
|
||||
|
||||
// generate any dns nodes on the graph
|
||||
dnsCheckNodes.forEach(function(node, i, a){
|
||||
node.x = 2;
|
||||
node.y = (0.6 * i / a.length) - 0.8;
|
||||
node.size = 10;
|
||||
node.color = "#4CC40B";
|
||||
if (!node._data.OK) {
|
||||
node.color = "red";
|
||||
}
|
||||
//console.log(node);
|
||||
s.graph.addNode(node);
|
||||
});
|
||||
|
||||
// generate the edges
|
||||
edges.forEach(function(edge, i){
|
||||
var color = "#ccc";
|
||||
@@ -255,6 +370,9 @@ var main = function(timeout){
|
||||
if (!edge._data.OK) {
|
||||
color = "red";
|
||||
}
|
||||
if ("isDNSCheckNode" in edge._data) {
|
||||
type = "dashed";
|
||||
}
|
||||
var edge = {
|
||||
id: "e" + i,
|
||||
source: edge.source,
|
||||
@@ -305,7 +423,7 @@ var main = function(timeout){
|
||||
$('#modal-title').html(node.id);
|
||||
$('#modal-body').html(prepareJSON(node._data));
|
||||
|
||||
// show the things
|
||||
// show the things
|
||||
$('#modal-window-code').modal('show');
|
||||
});
|
||||
s.bind("clickStage", function (e) {
|
||||
@@ -321,7 +439,7 @@ var main = function(timeout){
|
||||
$('#modal-title').html(edge.id);
|
||||
$('#modal-body').html(prepareJSON(edge._data));
|
||||
|
||||
// show the things
|
||||
// show the things
|
||||
$('#modal-window-code').modal('show');
|
||||
});
|
||||
})
|
||||
@@ -337,18 +455,31 @@ main();
|
||||
|
||||
$("#show-data").click(function (e) {
|
||||
// fill the voids
|
||||
$('#modal-title').html("/check_all");
|
||||
$('#modal-title').html("check_all");
|
||||
$('#modal-body').html(prepareJSON(global_data));
|
||||
|
||||
// show the things
|
||||
// show the things
|
||||
$('#modal-window-code').modal('show');
|
||||
});
|
||||
$("#reload-graph").click(function (e) {
|
||||
s.kill();
|
||||
main();
|
||||
});
|
||||
$("#show-heatmap").click(function (e) {
|
||||
updateHeatmap();
|
||||
$('#modal-window-heatmap').modal('show');
|
||||
});
|
||||
var updateHeatmap = function(){
|
||||
$('#heatmap-body').html(
|
||||
'<img src="' + getHeatmapUrl() + '" />'
|
||||
);
|
||||
}
|
||||
$("#update-heatmap").click(function (e) {
|
||||
updateHeatmap();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
||||
26
swagger.yml
26
swagger.yml
@@ -1,7 +1,7 @@
|
||||
---
|
||||
swagger: '2.0'
|
||||
info:
|
||||
version: 1.0.0
|
||||
version: 2.0.0
|
||||
title: Goldpinger
|
||||
definitions:
|
||||
CallStats:
|
||||
@@ -12,6 +12,17 @@ definitions:
|
||||
type: integer
|
||||
ping:
|
||||
type: integer
|
||||
DnsResult:
|
||||
properties:
|
||||
response-time-ms:
|
||||
type: number
|
||||
format: int64
|
||||
error:
|
||||
type: string
|
||||
DnsResults:
|
||||
type: object
|
||||
additionalProperties:
|
||||
$ref: '#/definitions/DnsResult'
|
||||
PingResults:
|
||||
type: object
|
||||
properties:
|
||||
@@ -42,8 +53,13 @@ definitions:
|
||||
description: wall clock time in milliseconds
|
||||
CheckResults:
|
||||
type: object
|
||||
additionalProperties:
|
||||
$ref: '#/definitions/PodResult'
|
||||
properties:
|
||||
dnsResults:
|
||||
$ref: '#/definitions/DnsResults'
|
||||
podResults:
|
||||
type: object
|
||||
additionalProperties:
|
||||
$ref: '#/definitions/PodResult'
|
||||
CheckAllPodResult:
|
||||
type: object
|
||||
properties:
|
||||
@@ -83,6 +99,10 @@ definitions:
|
||||
podIP:
|
||||
type: string
|
||||
format: ipv4
|
||||
dnsResults:
|
||||
type: object
|
||||
additionalProperties:
|
||||
$ref: '#/definitions/DnsResults'
|
||||
responses:
|
||||
type: object
|
||||
additionalProperties:
|
||||
|
||||
Reference in New Issue
Block a user