106 Commits

Author SHA1 Message Date
Mikolaj Pawlikowski
c66050e536 Merge pull request #78 from skamboj/migrate-to-go-modules
Migrate to go modules
2020-04-02 20:40:46 +01:00
Mikolaj Pawlikowski
34d84b233c Merge branch 'master' into migrate-to-go-modules 2020-04-02 17:56:00 +01:00
Mikolaj Pawlikowski
e07ae6a64c Merge pull request #75 from ifooth/master
fix prometheus ruler expr
2020-04-02 17:55:47 +01:00
Mikolaj Pawlikowski
6844a8d2b4 Merge branch 'master' into master 2020-04-02 17:36:43 +01:00
Sachin Kamboj
c23112de50 Update the CI
Signed-off-by: Sachin Kamboj <skamboj1@bloomberg.net>
2020-04-01 21:06:01 -04:00
Sachin Kamboj
436c1a7243 Update the README to remove references to dep
Signed-off-by: Sachin Kamboj <skamboj1@bloomberg.net>
2020-04-01 21:00:31 -04:00
Sachin Kamboj
66c8dc0cce Update the version/tag to be compatible with what go expects
Signed-off-by: Sachin Kamboj <skamboj1@bloomberg.net>
2020-04-01 20:53:45 -04:00
Sachin Kamboj
8a7e5a36ba Update the multistage build to use go 1.14 and go modules; Remove dep
Signed-off-by: Sachin Kamboj <skamboj1@bloomberg.net>
2020-04-01 20:26:03 -04:00
Sachin Kamboj
4e508cb8c8 Update the vendoring
Signed-off-by: Sachin Kamboj <skamboj1@bloomberg.net>
2020-04-01 20:17:37 -04:00
Sachin Kamboj
536a7ffbbb Remove the dep files
Signed-Off-By: Sachin Kamboj <skamboj1@bloomberg.net>
2020-04-01 20:16:47 -04:00
Sachin Kamboj
bf25a51c3e Add a go.mod and go.sum
Signed-Off-By: Sachin Kamboj <skamboj1@bloomberg.net>
2020-04-01 19:48:15 -04:00
Mikolaj Pawlikowski
02b38e3ab7 Merge pull request #77 from sandeepmendiratta/sandeep-heatmap_fix
minor typo correction in heat map page. Also updated version and Read…
2020-03-22 21:36:49 +00:00
Sandeep Mendiratta
0870833cf5 minor typo correction in heat map page. Also updated version and Readme with new version
Signed-off-by: Sandeep Mendiratta <smendiratta@yahoo.com>
2020-03-22 16:28:22 -05:00
Mikolaj Pawlikowski
d5400d6e2e Merge pull request #76 from seeker89/fix-empty-ips
Fix a Goldpinger reporting healthy when kubernetes returns an empty IP field
2020-03-11 14:21:05 +00:00
Mikolaj Pawlikowski
94d4a7c81e Use HostIP as podIP, if the there is no podIP
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-03-11 13:25:12 +00:00
Mikolaj Pawlikowski
94dc18c9c2 Update the version in README
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-03-11 13:05:22 +00:00
Mikolaj Pawlikowski
8964cab729 Bump patch version
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-03-11 13:05:22 +00:00
Mikolaj Pawlikowski
d297e2f3c6 Change CheckAllPods to return an error when can't create a server
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-03-11 13:05:22 +00:00
Mikolaj Pawlikowski
02067f03ab Change PingAllPods to send an error if the client can't be created
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-03-11 13:05:22 +00:00
Mikolaj Pawlikowski
b96cab34ea Change the client builder to fail, if the IP provided is empty, instead of defaulting to localhost
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-03-11 13:05:22 +00:00
Mikolaj Pawlikowski
bc7afb7a17 Return response time on failure to ping
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-03-11 13:05:22 +00:00
Mikolaj Pawlikowski
89a6c76c9c Formatting
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-03-11 13:05:22 +00:00
Joe Lei
60436daf18 fix prometheus ruler expr
Signed-off-by: Joe Lei <thezero12@hotmail.com>
2020-02-18 10:59:43 +08:00
Mikolaj Pawlikowski
618369f540 Merge pull request #71 from SuleimanWA/master
prometheus service auto-discovery
2019-11-26 20:13:58 +00:00
suleimanWA
1ab777c3d5 Merge branch 'master' of github.com:SuleimanWA/goldpinger
move scrap annotation from service to pod level

Signed-off-by: suleimanWA <suleiman-94@hotmail.com>
2019-11-26 20:52:46 +02:00
suleiman abualrob
6315c71a2c Update README.md
Kubernetes master node by most of default installation are taint, so goldPinger DaemonSet will not deployed to master, in order to make it run on master nodes also, you have to tolerate the taint

Signed-off-by: suleimanWA <suleiman-94@hotmail.com>
2019-11-26 20:42:27 +02:00
suleiman abualrob
49a47284b6 Update README.md
Kubernetes master node by most of default installation are taint, so goldPinger DaemonSet will not deployed to master, in order to make it run on master nodes also, you have to tolerate the taint

Signed-off-by: suleimanWA <suleiman-94@hotmail.com>
2019-11-26 20:38:52 +02:00
suleiman abualrob
ec2155878a Update README.md
If you have Prometheus in your environment, adding these annotation will let  Prometheus auto-discovery fetch your metrics automatically from service-name:port/metrics

Signed-off-by: suleimanWA <suleiman-94@hotmail.com>
2019-11-26 19:03:14 +02:00
Mikolaj Pawlikowski
cab268b725 Merge pull request #70 from angelbarrera92/secure-k8s-deployment
Secure k8s deployment
2019-11-14 16:53:06 +00:00
Ángel Barrera Sánchez
e552b236a0 Change documentation example
Signed-off-by: Ángel Barrera Sánchez <angel@sighup.io>
2019-11-14 17:19:42 +01:00
Ángel Barrera Sánchez
8a86a74478 Change dashboard's datasource parameter to be variable
Signed-off-by: Ángel Barrera Sánchez <angel@sighup.io>
2019-11-14 17:19:42 +01:00
Ángel Barrera Sánchez
4dab241ff6 Change daemonset definition to be more secure
Signed-off-by: Ángel Barrera Sánchez <angel@sighup.io>
2019-11-14 17:19:42 +01:00
Mikolaj Pawlikowski
f99ba84d17 Merge pull request #64 from seeker89/bump-major-version
Add info on how to use the DNS features
2019-09-06 15:10:44 +01:00
Mikolaj Pawlikowski
75315a872a Better wording in the README
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-09-06 14:58:10 +01:00
Mikolaj Pawlikowski
ae67cf3594 Add a note about the DNS addresses being space-delimited
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-09-06 14:57:08 +01:00
Mikolaj Pawlikowski
433a6b8b88 Add a note about the DNS usage
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-09-06 14:51:22 +01:00
Mikolaj Pawlikowski
0660db7922 Bump up major version to 2.0.0
Since this is effectively a backwards incompatible change

Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-09-06 14:42:36 +01:00
Mikolaj Pawlikowski
58285945f6 Merge pull request #61 from cgreen12/master
Optionally test DNS resolution for each pod
2019-09-06 12:23:36 +01:00
Mikolaj Pawlikowski
8a014ad7f4 Merge branch 'master' into master 2019-09-05 13:58:20 +01:00
Mikolaj Pawlikowski
096b149afa Merge pull request #63 from ufou/all_relative_paths
make all paths relative to allow for hosting at a sub path of root
2019-09-05 13:56:58 +01:00
Luke Alexander
5840353d9f bump patch version accordingly
Signed-off-by: Luke Alexander <luke.alexander@mixcloud.com>
2019-09-05 11:39:50 +01:00
Luke Alexander
ac9bf4224d make all paths relative to allow for hosting at a sub path of root
Signed-off-by: Luke Alexander <luke.alexander@mixcloud.com>
2019-09-05 11:10:23 +01:00
Chris Green
bcbc2ac6fc :trollface: re-ran swagger
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-08-21 04:53:01 -04:00
Chris Green
192fc433a2 Added metric for DNS failures
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-07-04 03:06:29 -04:00
Chris Green
dc3864f170 Colour the dns nodes red for any failures
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-09 09:11:49 -04:00
Chris Green
8a759433eb Show the info for dns nodes
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-09 08:53:52 -04:00
Chris Green
1b12b7dc6b Version bump
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-09 08:44:49 -04:00
Chris Green
9adf26e2cb Consistency ftw
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-09 08:43:47 -04:00
Chris Green
927125bbc5 slight re-positioning
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-09 07:37:48 -04:00
Chris Green
7585d010a6 Initial UI changes
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-05 14:56:37 -04:00
Chris Green
5e0ecdd8d1 Updates from swagger change
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-05 14:30:53 -04:00
Chris Green
d834433d30 Moved dns check into client
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-05 14:30:11 -04:00
Chris Green
b64f5152f2 Moved DnsResults into CheckResults
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-05 14:28:40 -04:00
Chris Green
bbac97c17e Refactored swagger.yml for fewer dns requests
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-04 02:54:23 -04:00
Chris Green
74ffcc8d2e Do the dns lookup
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-02 13:18:40 -04:00
Chris Green
9586e16237 Updated models from swagger
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-02 13:18:05 -04:00
Chris Green
6541250aa9 Updated swagger.yml for map of dnsresults
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-02 11:54:20 -04:00
Chris Green
31a503d831 Added env-delim for envvar config
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-02 11:18:25 -04:00
Chris Green
195691518b Added DnsHosts to config
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-01 15:18:26 -04:00
Chris Green
aa66c94d47 Initial thoughts on swagger change
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-01 11:41:01 -04:00
Mikolaj Pawlikowski
7b2affea29 Merge pull request #59 from kpfleming/travis-deploy-one-version
Ensure that only Golang 1.10 builds are pushed to DockerHub
2019-03-22 15:27:12 +00:00
Kevin P. Fleming
d1a86eae93 Ensure that only Golang 1.10 builds are pushed to DockerHub
Signed-off-by: Kevin P. Fleming <kpfleming@bloomberg.net>
2019-03-21 16:16:22 -04:00
Mikolaj Pawlikowski
a2e5925210 Merge pull request #58 from dannyk81/healthz_readme
Update readme and example with liveness and readiness probes
2019-03-18 09:56:04 +00:00
Danny Kulchinsky
d243f0fb59 update example
Signed-off-by: Danny Kulchinsky <danny.kul@gmail.com>
Signed-off-by: Danny Kulchinsky <dannyk@tuenti.com>
2019-03-17 21:01:15 -04:00
Danny Kulchinsky
477ba69a72 Add livenessProbe and readinessProbe to README
Signed-off-by: Danny Kulchinsky <danny.kul@gmail.com>
Signed-off-by: Danny Kulchinsky <dannyk@tuenti.com>
2019-03-17 21:01:15 -04:00
Mikolaj Pawlikowski
86064f208e Merge pull request #53 from stuartnelson3/stn/rendezvous-hashing
Add rendezvous hash for selecting subset of nodes
2019-03-14 12:24:33 +00:00
Mikolaj Pawlikowski
d8f8c20927 make the graph work with edges to nodes that are not reporting
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-14 08:13:44 -04:00
Mikolaj Pawlikowski
7c43626b1e Minor version bump to 1.5.0
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-14 11:28:32 +00:00
Mikolaj Pawlikowski
11ec058b3b Add PING_NUMBER envvar support
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-14 11:27:49 +00:00
Mikolaj Pawlikowski
c006eede86 Merge branch 'master' into stn/rendezvous-hashing 2019-03-13 17:11:23 +00:00
Mikolaj Pawlikowski
a585b103f3 Merge pull request #56 from seeker89/docker-push-updates
Updates for the docker images being pushed to docker.io
2019-03-13 17:09:50 +00:00
Mikolaj Pawlikowski
32823fd105 remove the ls and pwd artifacts
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-13 16:58:42 +00:00
Mikolaj Pawlikowski
87792cffca turns out vendor folder I tried to copy was in gitignore and Travis won't pick it up
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-13 16:52:23 +00:00
Mikolaj Pawlikowski
369e9ece78 add slashes for the folders to copy
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-13 16:47:48 +00:00
Mikolaj Pawlikowski
28af41e352 Revert "debugging Travis - see if the ARG makes a difference"
This reverts commit 52ea5546aa.

Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-13 16:47:08 +00:00
Mikolaj Pawlikowski
52ea5546aa debugging Travis - see if the ARG makes a difference
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-13 16:41:12 +00:00
Mikolaj Pawlikowski
9040b69933 debug the make vendor-build target
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-13 16:23:17 +00:00
Mikolaj Pawlikowski
3ce0c46f91 consistenly use COPY over ADD
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-13 16:15:13 +00:00
Mikolaj Pawlikowski
7b156add72 Revert "fix the path to copy vendor folder from"
This reverts commit 8b1dd49506.

Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-13 15:53:37 +00:00
Mikolaj Pawlikowski
8b1dd49506 fix the path to copy vendor folder from
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-13 15:46:22 +00:00
Mikolaj Pawlikowski
bd13d4d673 simplify the vendor building, make it build it with every Travis run
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-13 14:43:09 +00:00
stuart nelson
895af850a1 Make PodSelecter a member on config struct
Signed-off-by: stuart nelson <stuartnelson3@gmail.com>
2019-03-13 15:30:18 +01:00
stuart nelson
771f303062 Add rendezvous hash for selecting subset of nodes
Select a user-defined number of pods via
rendezvous hash. This is important for larger
clusters, where the metric cardinality explosion
is too much for a single prometheus to handle.

Signed-off-by: stuart nelson <stuartnelson3@gmail.com>
2019-03-13 15:30:18 +01:00
Mikolaj Pawlikowski
b7c1d2dfb4 add extra info in README, about the -vendor image tag
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-13 14:29:54 +00:00
Mikolaj Pawlikowski
86ddcf9505 push an additional image with -vendor postfix with all the sources
For licensing reasons.

Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-13 14:26:28 +00:00
Mikolaj Pawlikowski
bf43dcff98 remove the vendor from the standard build
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-13 14:13:17 +00:00
Mikolaj Pawlikowski
6de72deee0 When building multi-stage, copy over the vendor folder for licensing reasons
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-13 13:59:43 +00:00
Mikolaj Pawlikowski
6cd12ef2d5 Update example-with-kubeconfig.yaml
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-12 23:07:54 +00:00
Mikolaj Pawlikowski
8182369c02 Update example-serviceaccounts.yml
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-12 23:07:29 +00:00
Mikolaj Pawlikowski
82a0d6ae8c Merge branch 'master' into docker-push-updates 2019-03-12 23:05:32 +00:00
Mikolaj Pawlikowski
057e360c5b Update README.md
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-03-12 22:59:32 +00:00
Mikolaj Pawlikowski
4cf5dea621 Merge pull request #55 from kpfleming/travis-to-dockerhub
Enable push of images to DockerHub
2019-03-12 22:35:50 +00:00
Kevin P. Fleming
16a1d52741 Deployment improvements
* Only deploy from tags
* Only attempt deployment if DOCKER_PASSWORD has been set in environment
* Don't cleanup working directory before deployment

Signed-off-by: Kevin P. Fleming <kpfleming@bloomberg.net>
2019-03-12 09:15:22 -04:00
Kevin P. Fleming
0472791dae Use a 'deploy' stage and script
Pushing to DockerHub from the 'after_success' phase
was unreliable (triggered by PRs) so this patch changes
the process to use a 'deploy' stage script instead.

Signed-off-by: Kevin P. Fleming <kpfleming@bloomberg.net>
2019-03-11 16:28:16 -04:00
Kevin P. Fleming
84a43a3d28 Enable push of images to DockerHub
This patch will enable pushes of any successful builds (using Travis-CI)
of the 'master' branch to the proper repository on DockerHub. The credentials
necessary are provided via environment variables configured in the
Travis-CI settings.

Addresses issue #27

Signed-off-by: Kevin P. Fleming <kpfleming@bloomberg.net>
2019-03-11 15:29:58 -04:00
Mikolaj Pawlikowski
3f70a24804 Merge pull request #51 from seeker89/heatmap
Add heatmap
2019-03-05 17:48:00 +00:00
Mikolaj Pawlikowski
593307dc01 change the block size to 14 pixels (enough for two digits, so 100 machines cluster)
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-02-22 17:32:22 +00:00
Mikolaj Pawlikowski
950e2e4ab7 dep ensure
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-02-21 18:36:25 +00:00
Mikolaj Pawlikowski
d8f0d696ea add a basic legend to the heatmap image
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-02-21 18:34:30 +00:00
Mikolaj Pawlikowski
6deb5c3044 fix static folder when using Dockerfile-simple
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-02-21 17:43:54 +00:00
Mikolaj Pawlikowski
767d2dba7f quick test of how to integrate with the UI
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-02-21 17:41:19 +00:00
Mikolaj Pawlikowski
2efee0f5e5 read the tresholds from the query params
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-02-21 17:40:06 +00:00
Mikolaj Pawlikowski
3a729bf196 minor version bump
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-02-21 16:14:48 +00:00
Mikolaj Pawlikowski
fd84599157 remove debug print statements
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-02-21 16:13:20 +00:00
Mikolaj Pawlikowski
f5c2763000 add an endpoint for generating a /heatmap.png
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-02-21 13:51:20 +00:00
Mikolaj Pawlikowski
22b96d001d add a skeleton for creating a heatmap png
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-02-21 13:50:59 +00:00
37 changed files with 1243 additions and 900 deletions

View File

@@ -1,2 +1 @@
.git/
/vendor/

View File

@@ -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"

View File

@@ -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
View File

@@ -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

View File

@@ -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

View File

@@ -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
View File

@@ -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 ![Build Status](https://travis-ci.com/bloomberg/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:
![screenshot-DNS-resolution](./extras/dns-screenshot.png)
## 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`.

View File

@@ -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
View File

@@ -0,0 +1,3 @@
ARG TAG
FROM $TAG
COPY vendor /goldpinger-vendor-sources

View File

@@ -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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

View File

@@ -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:

View File

@@ -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:

View File

@@ -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
View 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
View 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=

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
View 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)
}
}

View 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
}

View File

@@ -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(

View File

@@ -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()))
}

View File

@@ -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

View File

@@ -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

View File

@@ -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
View 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
View 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
}

View File

@@ -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 {

View File

@@ -7,7 +7,7 @@ Package restapi Goldpinger
http
Host: localhost
BasePath: /
Version: 1.0.0
Version: 2.0.0
Consumes:
- application/json

View File

@@ -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": {

View File

@@ -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
}
}
}

View File

@@ -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

View File

@@ -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)"`

View File

@@ -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">&times;</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">&times;</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">&times;</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>

View File

@@ -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: