119 Commits

Author SHA1 Message Date
skamboj
0b96e45e05 Merge pull request #140 from cloudeteer/feature/windows-build
Provide Windows builds and refactor CI
2023-11-08 20:47:59 -05:00
Jan-Otto Kröpke
fc076f9d71 Use full imags base name as ARG
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
2023-11-03 18:25:42 +01:00
Chris Jedro
166f65fe4d fix dockerfile
Signed-off-by: Chris Jedro <cj@cloudeteer.de>
2023-11-03 11:21:14 +01:00
Jan-Otto Kröpke
e5ca7ec03f Provide Windows builds and refactor CI
Signed-off-by: Jan-Otto Kröpke <joe@cloudeteer.de>
2023-11-02 20:51:16 +01:00
skamboj
640e4430cf Merge pull request #139 from skamboj/update-golang
Update golang
2023-10-22 19:52:34 -04:00
Sachin Kamboj
2a684a8aef OOPS - accidentally left out the target on doing the update
Signed-off-by: Sachin Kamboj <skamboj1@bloomberg.net>
2023-10-22 22:13:44 +00:00
Sachin Kamboj
1d9a533433 Update to golang 1.21 in the github workflow as well
Signed-off-by: Sachin Kamboj <skamboj1@bloomberg.net>
2023-10-22 22:07:16 +00:00
Sachin Kamboj
e59a14d574 Update the builder image and use distroless for the final image
Signed-off-by: Sachin Kamboj <skamboj1@bloomberg.net>
2023-10-22 22:04:07 +00:00
Sachin Kamboj
9b0b5449d5 :trollface: seriously? how was this broken
Signed-off-by: Sachin Kamboj <skamboj1@bloomberg.net>
2023-10-22 17:36:32 +00:00
Sachin Kamboj
cd3680af09 Update go.sum
Signed-off-by: Sachin Kamboj <skamboj1@bloomberg.net>
2023-10-22 17:35:57 +00:00
Sachin Kamboj
84aa0c443d Update all the dependencies...
Signed-off-by: Sachin Kamboj <skamboj1@bloomberg.net>
2023-10-22 17:35:36 +00:00
skamboj
bd541d4a11 Merge pull request #129 from wedaly/rbac-authorization-version
Remove deprecated rbac.authorization.k8s.io/v1beta1
2023-08-21 21:21:32 -04:00
Will Daly
1f3ad0acc9 Remove deprecated rbac.authorization.k8s.io/v1beta1
This commit updates the README and examples to use
rbac.authorization.k8s.io/v1 instead, which has been available
since K8s 1.8

rbac.authorization.k8s.io/v1beta1 was deprecated in K8s 1.17
and removed in K8s 1.22.

Reference:
https://kubernetes.io/docs/reference/using-api/deprecation-guide/#rbac-resources-v122

Signed-off-by: Will Daly <widaly@microsoft.com>
2023-05-03 11:29:42 -07:00
Mikolaj Pawlikowski
95363554e4 Merge pull request #124 from maxime1907/feat-config-zap
feat: support advanced zap configuration
2022-10-25 20:37:40 +01:00
Maxime Leroy
a913318ae3 feat: support advanced zap configuration
Signed-off-by: Maxime Leroy <19607336+maxime1907@users.noreply.github.com>
2022-10-25 12:30:35 +02:00
Mikolaj Pawlikowski
2f54105404 Merge pull request #121 from kitfoman/add-missing-dependency
[Bug Fix] add missing dependency
2022-08-29 16:55:12 +01:00
kitfoman
f6dbd2632b add missing dependency
Signed-off-by: kitfoman <thaddeusgetachew@gmail.com>
2022-08-29 10:41:39 -04:00
Mikolaj Pawlikowski
8ad0802439 Merge pull request #115 from kitfoman/add-external-probes
Extend DNS resolver to include TCP and HTTP checks for external targets
2022-08-26 21:05:02 +01:00
Tadewos Getachew
7cd571d15f Merge branch 'master' into add-external-probes 2022-05-08 22:06:35 -04:00
tgetachew
14ea96999a add external probes
Signed-off-by: kitfoman <thaddeusgetachew@gmail.com>

make timeout flags backwards compatible

Signed-off-by: kitfoman <thaddeusgetachew@gmail.com>
2022-05-08 22:02:09 -04:00
Tyler Lloyd
05ab610f10 cleanup IPv6 references
only check node IPs when determining hostIP

IP_VERSIONS not IP_FAMILIES

Signed-off-by: Tyler Lloyd <tyler.lloyd@microsoft.com>
2022-05-08 22:02:03 -04:00
Mikolaj Pawlikowski
1a9ae3a9ba Merge pull request #116 from tyler-lloyd/cleanup-ipv6
Cleanup ipv6
2022-04-15 14:09:45 +01:00
Mikolaj Pawlikowski
d976605bc6 Merge branch 'master' into cleanup-ipv6 2022-04-15 13:37:54 +01:00
Mikolaj Pawlikowski
5cc9bd55ad Merge pull request #119 from XIAOMI-CloudNative/feat/show-nodename
Fix pinger be removed by not found.
2022-04-15 13:36:46 +01:00
wanglijie6
72832bcbc4 Fix pinger be removed by not found.
heatmap will be broken in every refeshPeriod,
I found pinger is be deleted because of exists check faild.

updatePingers will check if a pod still exist or a new one,
and update pingers in every refreshPeriod.

the function exists failed to check pod exist, so fix it.

Signed-off-by: wanglijie6 <wanglijie6@xiaomi.com>
2022-04-15 19:14:53 +08:00
Mikolaj Pawlikowski
a461b0ffd5 Merge pull request #118 from XIAOMI-CloudNative/feat/show-nodename
Display hostName other than podName
2022-04-14 17:15:41 +01:00
wanglijie6
7609a3ab3f Add --display-nodename option to control UI display
Add GoldpingerConfig.DisplayNodeName to control UI display, default is
`false`, which means to display podName

Signed-off-by: wanglijie6 <wanglijie6@xiaomi.com>
2022-04-13 10:54:59 +08:00
wanglijie6
588c1a0173 Show hostName other than podName
Signed-off-by: wanglijie6 <wanglijie6@xiaomi.com>
2022-04-12 20:06:48 +08:00
Tyler Lloyd
ef300d5ca2 cleanup IPv6 references
only check node IPs when determining hostIP

IP_VERSIONS not IP_FAMILIES

Signed-off-by: Tyler Lloyd <tyler.lloyd@microsoft.com>
2022-03-30 17:42:22 +00:00
Mikolaj Pawlikowski
79bb860f11 Merge pull request #114 from bloomberg/seeker89-patch-1
Even more GH action tweaks
2022-02-07 16:38:43 +00:00
Mikolaj Pawlikowski
94965624cf No need for that either, fix vendor tag
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-04 15:51:52 +00:00
Mikolaj Pawlikowski
c49fc9925c No need for this
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-04 15:50:53 +00:00
Mikolaj Pawlikowski
114b39a970 Merge pull request #113 from bloomberg/seeker89-patch-1
Trying to get the GH actions right
2022-02-04 15:36:01 +00:00
Mikolaj Pawlikowski
00ca071c22 Remove the GO_MOD_ACTION
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-04 15:03:56 +00:00
Mikolaj Pawlikowski
0715e438b9 Always vendor
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-04 15:01:55 +00:00
Mikolaj Pawlikowski
c3a37636c3 Also dockerignore vendor folder
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-04 11:42:21 +00:00
Mikolaj Pawlikowski
5961c48854 Easier to read
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-04 11:39:00 +00:00
Mikolaj Pawlikowski
3f4d041c17 Dockerignore the bin folder
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-04 11:07:28 +00:00
Mikolaj Pawlikowski
9acc894fde Update publish.yml
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-04 11:06:12 +00:00
Mikolaj Pawlikowski
f1ee7f5a49 Merge pull request #112 from bloomberg/seeker89-patch-1
Fix the build badge
2022-02-04 10:56:09 +00:00
Mikolaj Pawlikowski
76f054ba50 Fix the build badge
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-04 10:51:43 +00:00
Mikolaj Pawlikowski
406f6e0ed0 Merge pull request #111 from bloomberg/seeker89-patch-1
Fix GH image publishing
2022-02-04 10:48:49 +00:00
Mikolaj Pawlikowski
b907f30c2f Update main.yml
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-04 10:44:59 +00:00
Mikolaj Pawlikowski
d304200ede Update publish.yml
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-04 10:43:56 +00:00
Mikolaj Pawlikowski
0755c8521f Merge pull request #110 from bloomberg/github-actions
Move onto Github Actions
2022-02-03 16:27:42 +00:00
Mikolaj Pawlikowski
9b1d8f8195 Run the docker image to see it works
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-03 12:34:56 +00:00
Mikolaj Pawlikowski
3cda043118 Cleanup the Makefile
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-03 12:33:06 +00:00
Mikolaj Pawlikowski
555709de0a Fix the tags and labels for the vendor build
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-03 12:28:49 +00:00
Mikolaj Pawlikowski
f89a07a420 Also do multi-arch builds on CI
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-03 12:27:30 +00:00
Mikolaj Pawlikowski
30f4d378f5 Delete Dockerfile-vendor
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-03 12:21:38 +00:00
Mikolaj Pawlikowski
b4ffe5dea2 Delete Dockerfile-simple
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-03 12:21:26 +00:00
Mikolaj Pawlikowski
42632de0cb Backwards compatible
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-03 12:17:50 +00:00
Mikolaj Pawlikowski
2f77502b0a Formatting
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-03 12:13:10 +00:00
Mikolaj Pawlikowski
46bc22ef0f Re-add basic CI with GH actions
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-03 12:12:07 +00:00
Mikolaj Pawlikowski
10277adc58 Update the secret names
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-03 12:09:58 +00:00
Mikolaj Pawlikowski
50ac3f0101 Delete .travis.yml
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-03 12:03:16 +00:00
Mikolaj Pawlikowski
56b438abad Delete docker_deploy.sh
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2022-02-03 12:02:37 +00:00
Mikolaj Pawlikowski
fcc30fbe75 Merge pull request #109 from mtougeron/multi-arch-build
[WORK IN PROGRESS] Multi-architecture builds for goldpinger
2022-02-03 11:58:43 +00:00
Mike Tougeron
6aee150cd0 Multi-arch builds for goldpinger
Signed-off-by: Mike Tougeron <tougeron@adobe.com>
2022-01-15 17:12:42 -08:00
Mikolaj Pawlikowski
f7509473f6 Merge pull request #108 from bloomberg/version3-3-0
Version 3.3.0
2021-11-09 17:00:10 +00:00
Mikolaj Pawlikowski
039362ff78 Version 3.3.0
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-11-09 16:53:05 +00:00
Mikolaj Pawlikowski
b5f352def1 Merge pull request #107 from rbtr/list-running-pods
only list running pods
2021-11-08 15:41:13 +00:00
Mikolaj Pawlikowski
842dfadeea Merge branch 'master' into list-running-pods 2021-11-08 15:11:18 +00:00
Mikolaj Pawlikowski
ba58fcfaa0 Merge pull request #106 from tyler-lloyd/tyler-lloyd/enable-ipv6
Enable ping traffic over IPv6 via @tyler-lloyd
2021-11-08 15:09:48 +00:00
Tyler Lloyd
34b78537c9 changed return type to IPFamily
Signed-off-by: Tyler Lloyd <Tyler.Lloyd@microsoft.com>
2021-11-08 09:38:38 -05:00
Tyler Lloyd
ae61217ead cleanup imports
Signed-off-by: Tyler Lloyd <Tyler.Lloyd@microsoft.com>
2021-11-05 10:41:29 -04:00
Tyler Lloyd
cfd26c8d26 changing to IP_VERSIONS
Signed-off-by: Tyler Lloyd <Tyler.Lloyd@microsoft.com>
2021-11-05 10:40:37 -04:00
Evan Baker
980a85b04d only list running pods
Signed-off-by: Evan Baker <rbtr@users.noreply.github.com>
2021-11-03 18:06:29 -05:00
Tyler Lloyd
b88d0f3ec5 don't use Sprintf for creating host address
Signed-off-by: Tyler Lloyd <Tyler.Lloyd@microsoft.com>
2021-11-03 16:58:38 -04:00
Tyler Lloyd
03dd6706b8 add node IP cache and change to get node
Signed-off-by: Tyler Lloyd <Tyler.Lloyd@microsoft.com>
2021-11-03 16:58:38 -04:00
Tyler Lloyd
f76b552c62 reverting to go 1.14
Signed-off-by: Tyler Lloyd <Tyler.Lloyd@microsoft.com>
2021-11-03 16:58:38 -04:00
Tyler Lloyd
5b080c7087 update readme for IPv6 example
Signed-off-by: Tyler Lloyd <Tyler.Lloyd@microsoft.com>
2021-11-03 16:58:38 -04:00
Tyler Lloyd
5d2070fad1 get pod and host IPv6 IPs when USE_IPV6 is set
Signed-off-by: Tyler Lloyd <Tyler.Lloyd@microsoft.com>
2021-11-03 16:58:38 -04:00
Tyler Lloyd
b35d40b7f2 bumping to go 1.16 and updating k8s packages
Signed-off-by: Tyler Lloyd <Tyler.Lloyd@microsoft.com>
2021-11-03 16:58:38 -04:00
Mikolaj Pawlikowski
294b8dda19 Merge pull request #101 from bloomberg/cluster-health
Add a /cluster_health endpoint
2021-03-22 13:26:32 +00:00
Mikolaj Pawlikowski
ed40304dd8 1 when healthy, 0 when unhealthy (bool, not return code)
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-19 14:45:58 +00:00
Mikolaj Pawlikowski
e6aa196232 Compare the actual host ips
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-19 14:26:07 +00:00
Mikolaj Pawlikowski
948b67a09b Break here, continue there
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-19 13:46:37 +00:00
Mikolaj Pawlikowski
d0e2e25ad2 Make it a bit more obvious
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-19 13:43:40 +00:00
Mikolaj Pawlikowski
8d5262d316 Make the naming a little less bad, remove the break statements
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-19 13:25:39 +00:00
Mikolaj Pawlikowski
407d201591 Add an overall metric goldpinger_cluster_health_total (pings + DNS check)
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-19 12:31:49 +00:00
Mikolaj Pawlikowski
1f5589db8c Simplify
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-16 17:24:56 +00:00
Mikolaj Pawlikowski
bc94f4e058 Forgot the set the default to true, if nothing bad happens
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-16 17:21:46 +00:00
Mikolaj Pawlikowski
634e04ec44 Handle the situation when one of the nodes returns an error
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 17:51:12 +00:00
Mikolaj Pawlikowski
13ae09d93e Compare all nodes return the expected nodes that Kubernetes returns
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 17:16:58 +00:00
Mikolaj Pawlikowski
52ff43ec7d Make it return 418 on cluster health problem
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 17:06:57 +00:00
Mikolaj Pawlikowski
bfc4603e45 Always return the DurationNs
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 13:38:32 +00:00
Mikolaj Pawlikowski
e4d0a6cdf7 Merge branch 'master' into cluster-health 2021-03-12 13:33:33 +00:00
Mikolaj Pawlikowski
ad828cf5a3 And implement it
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 13:31:39 +00:00
Mikolaj Pawlikowski
5d2ad6ce19 Also add a total number of nodes in a field for convenience
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 13:31:01 +00:00
Mikolaj Pawlikowski
1310f9b12b Add the generated at field
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 13:27:19 +00:00
Mikolaj Pawlikowski
f93526c58f Lint
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 13:27:07 +00:00
Mikolaj Pawlikowski
1f2f00ba35 First draft of implementing it
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 13:24:58 +00:00
Mikolaj Pawlikowski
807f193b07 Regenerate
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 13:06:26 +00:00
Mikolaj Pawlikowski
b0730e88df Actually, just keep it simple
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 13:05:53 +00:00
Mikolaj Pawlikowski
e827a8dc67 Regenearte the code
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 12:57:20 +00:00
Mikolaj Pawlikowski
c7a7008bf5 Separately for the pods and hosts
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 12:56:27 +00:00
Mikolaj Pawlikowski
3edecea467 Implement a stub of the new endpoint
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 12:24:42 +00:00
Mikolaj Pawlikowski
bd04fcbc58 Version v3.2.0
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 11:31:26 +00:00
Mikolaj Pawlikowski
3ff592b1e8 Re-generate using the latest swagger gen cli
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 11:30:53 +00:00
Mikolaj Pawlikowski
8f5c742aed Merge pull request #100 from bloomberg/v3.1.0
Bump up to v3.1.0
2021-03-12 11:22:11 +00:00
Mikolaj Pawlikowski
eb3113aa7f Add the schema for the new endpoint
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 11:21:02 +00:00
Mikolaj Pawlikowski
8865ae1411 Bump up to v3.1.0
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2021-03-12 11:07:55 +00:00
Mikolaj Pawlikowski
9ad2f6191a Merge pull request #98 from sethp-verica/feat/namespace-config
feat: configurable namespace for pod discovery
2021-03-12 11:05:36 +00:00
Seth Pellegrino
07ef524aed feat: configurable namespace for pod discovery
Adds a configuration option to allow for cross-namespace pings.

Signed-off-by: Seth Pellegrino <seth@verica.io>
2020-11-23 14:01:25 -08:00
Mikolaj Pawlikowski
ca676bcbc2 Merge pull request #91 from johscheuer/correct-readme
Correct example in the readme
2020-07-22 18:51:09 +01:00
Johannes M. Scheuermann
97ec159852 Correct example in the readme
Signed-off-by: Johannes M. Scheuermann <joh.scheuer@gmail.com>
2020-07-22 14:00:45 +02:00
Mikolaj Pawlikowski
bb1a72866d Merge pull request #89 from seeker89/readme3
Refresh the README
2020-06-10 22:30:13 +01:00
Mikolaj Pawlikowski
6e29c16148 Specify the size
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-06-10 22:24:17 +01:00
Mikolaj Pawlikowski
f83c1de387 MOAR hyperlinks
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-06-10 22:22:44 +01:00
Mikolaj Pawlikowski
e24f789b68 Hyperlink all the things
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-06-10 22:22:05 +01:00
Mikolaj Pawlikowski
3a922f4278 Some more polish
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-06-10 22:20:16 +01:00
Mikolaj Pawlikowski
24d74544e0 Well, I clearly don't know my emoticons
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-06-10 22:19:11 +01:00
Mikolaj Pawlikowski
28f7655170 Add a note about Chaos Engineering and the authors
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-06-10 22:17:28 +01:00
Mikolaj Pawlikowski
e9d3f8cd2b Refresh the readme a little bit
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-06-10 22:17:09 +01:00
Mikolaj Pawlikowski
857db0d523 Merge pull request #85 from bloomberg/seeker89-patch-1
Update examples and README to use v3.0.0 of Goldpinger
2020-05-08 13:09:18 +01:00
Mikolaj Pawlikowski
0260da795f Update example-with-kubeconfig.yaml
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-05-08 11:44:30 +01:00
Mikolaj Pawlikowski
4f8d872700 Update example-serviceaccounts.yml
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-05-08 11:44:30 +01:00
Mikolaj Pawlikowski
8790d3e7c4 Update README to use v3.0.0 of Goldpinger
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2020-05-08 11:44:30 +01:00
68 changed files with 2765 additions and 633 deletions

View File

@@ -1 +1,3 @@
.git/
bin/
vendor/

83
.github/workflows/main.yml vendored Normal file
View File

@@ -0,0 +1,83 @@
name: CI
on:
push:
branches: [ main, master ]
tags:
- v*
pull_request:
branches: [ main, master ]
workflow_dispatch:
jobs:
build:
permissions:
contents: write
packages: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version-file: 'go.mod'
# local build
- name: Compile the binary
run: |
make bin/goldpinger
./bin/goldpinger -h
# simple Docker build
- name: Build the Docker image
run: |
make build
docker run `make version` --help
- name: Login to DockerHub
uses: docker/login-action@v3
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# multi-arch build
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
bake-target: docker-metadata-action
images: |
${{ github.repository_owner }}/goldpinger
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
labels: |
org.opencontainers.image.title=${{ github.repository }}
org.opencontainers.image.description=Goldpinger makes calls between its instances to monitor your networking. It runs as a DaemonSet on Kubernetes and produces Prometheus metrics that can be scraped, visualised and alerted on.
org.opencontainers.image.vendor=${{ github.repository_owner }}
- name: Build regular image
uses: docker/bake-action@v4
with:
targets: ci
push: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
files: |
./docker-bake.hcl
${{ steps.meta.outputs.bake-file }}
# https://github.com/docker/buildx/issues/2105
- name: Create manifest
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
run: |
set -xe
for image in $images; do
docker buildx imagetools create -t "${image}" "${image}-linux" "${image}-windows-ltsc2019" "${image}-windows-ltsc2022"
done
env:
images: "${{ join( steps.meta.outputs.tags, ' ') }}"

View File

@@ -1,38 +0,0 @@
language: go
services:
- docker
go:
- "1.14.x"
- master
script:
- docker --version
# 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,23 +1,33 @@
FROM golang:1.14-alpine as builder
ARG WINDOWS_BASE_IMAGE=mcr.microsoft.com/windows/nanoserver:ltcs2022
# Install our build tools
RUN apk add --update git make bash
FROM --platform=$BUILDPLATFORM golang:1.21 as builder
ARG TARGETARCH
ARG TARGETOS
# Get dependencies
WORKDIR /w
COPY go.mod go.sum /w/
COPY go.mod go.sum ./
RUN go mod download
# Build goldpinger
COPY . ./
RUN make bin/goldpinger
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH make bin/goldpinger
# Create vendor folder
RUN go mod vendor
# Build the asset container, copy over goldpinger
FROM scratch
FROM gcr.io/distroless/static:nonroot as simple
COPY --from=builder /w/bin/goldpinger /goldpinger
COPY ./static /static
COPY ./config /config
ENTRYPOINT ["/goldpinger", "--static-file-path", "/static"]
FROM $WINDOWS_BASE_IMAGE AS windows
COPY --from=builder /w/bin/goldpinger /goldpinger.exe
COPY ./static /static
COPY ./config /config
ENTRYPOINT ["/goldpinger.exe", "--static-file-path=/static"]
# For vendor builds, use the simple build and add the vendor'd files
FROM simple as vendor
COPY --from=builder /w/vendor /goldpinger-vendor-sources

View File

@@ -1,15 +1,16 @@
name ?= goldpinger
version ?= v3.0.0
version ?= v3.7.0
bin ?= goldpinger
pkg ?= "github.com/bloomberg/goldpinger"
tag = $(name):$(version)
goos ?= ${GOOS}
goarch ?= ${GOARCH}
namespace ?= "bloomberg/"
files = $(shell find . -iname "*.go")
bin/$(bin): $(files)
GOOS=${goos} PKG=${pkg} ARCH=amd64 VERSION=${version} BIN=${bin} ./build/build.sh
GOOS=${goos} PKG=${pkg} ARCH=${goarch} VERSION=${version} BIN=${bin} ./build/build.sh
clean:
rm -rf ./vendor
@@ -24,34 +25,21 @@ swagger:
swagger generate server -t pkg -f ./swagger.yml --exclude-main -A goldpinger && \
swagger generate client -t pkg -f ./swagger.yml -A goldpinger
build-multistage:
docker build -t $(tag) -f ./Dockerfile .
build: GOOS=linux
build: bin/$(bin)
docker build -t $(tag) -f ./build/Dockerfile-simple .
tag:
docker tag $(tag) $(namespace)$(tag)
push:
docker push $(namespace)$(tag)
run:
go run ./cmd/goldpinger/main.go
build:
docker build -t $(namespace)$(tag) --target simple -f ./Dockerfile .
build-vendor:
docker build -t $(namespace)$(tag)-vendor --target vendor -f ./Dockerfile .
build-release:
docker buildx build --push --platform linux/amd64,linux/arm64 --target simple -t $(namespace)$(tag) -f ./Dockerfile .
docker buildx build --push --platform linux/amd64,linux/arm64 --target vendor -t $(namespace)$(tag)-vendor -f ./Dockerfile .
version:
@echo $(tag)
@echo $(namespace)$(tag)
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
.PHONY: clean vendor swagger build build-release build-vendor run version

View File

@@ -1,16 +1,19 @@
# Goldpinger [![Build Status](https://travis-ci.com/bloomberg/goldpinger.svg?branch=master)](https://travis-ci.com/bloomberg/goldpinger)
# Goldpinger
__Goldpinger__ makes calls between its instances for visibility and alerting.
It runs as a `DaemonSet` on `Kubernetes` and produces `Prometheus` metrics that can be scraped, visualised and alerted on.
[![Publish](https://github.com/bloomberg/goldpinger/actions/workflows/publish.yml/badge.svg)](https://github.com/bloomberg/goldpinger/actions/workflows/publish.yml)
__Goldpinger__ makes calls between its instances to monitor your networking.
It runs as a [`DaemonSet`](#example-yaml) on `Kubernetes` and produces `Prometheus` metrics that can be [scraped](#prometheus), [visualised](#grafana) and [alerted](#alert-manager) on.
Oh, and it gives you the graph below for your cluster. Check out the [video explainer](https://youtu.be/DSFxRz_0TU4).
![](./extras/screenshot.png)
[:tada: 1M+ pulls from docker hub!](https://hub.docker.com/r/bloomberg/goldpinger/tags)
## On the menu
- [Goldpinger ![Build Status](https://travis-ci.com/bloomberg/goldpinger)](#goldpinger-build-statushttpstravis-cicombloomberggoldpinger)
- [Goldpinger](#goldpinger)
- [On the menu](#on-the-menu)
- [Rationale](#rationale)
- [Quick start](#quick-start)
@@ -27,6 +30,8 @@ Oh, and it gives you the graph below for your cluster. Check out the [video expl
- [Prometheus](#prometheus)
- [Grafana](#grafana)
- [Alert Manager](#alert-manager)
- [Chaos Engineering](#chaos-engineering)
- [Authors](#authors)
- [Contributions](#contributions)
- [License](#license)
@@ -34,11 +39,10 @@ Oh, and it gives you the graph below for your cluster. Check out the [video expl
We built __Goldpinger__ to troubleshoot, visualise and alert on our networking layer while adopting `Kubernetes` at Bloomberg. It has since become the go-to tool to see connectivity and slowness issues.
It's small, simple and you'll wonder why you hadn't had it before.
It's small (~16MB), simple and you'll wonder why you hadn't had it before.
If you'd like to know more, you can watch [our presentation at Kubecon 2018 Seattle](https://youtu.be/DSFxRz_0TU4).
## Quick start
Getting from sources:
@@ -52,7 +56,7 @@ Getting from [docker hub](https://hub.docker.com/r/bloomberg/goldpinger):
```sh
# get from docker hub
docker pull bloomberg/goldpinger
docker pull bloomberg/goldpinger:v3.0.0
```
## Building
@@ -64,21 +68,20 @@ The repo comes with two ways of building a `docker` image: compiling locally, an
You will need `docker` version 17.05+ installed to support multi-stage builds.
```sh
# step 1: launch the build
make build-multistage
# Build a local container without publishing
make build
# step 2: push the image somewhere
namespace="docker.io/myhandle/" make tag
namespace="docker.io/myhandle/" make push
# Build & push the image somewhere
namespace="docker.io/myhandle/" make build-release
```
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.13+ and `docker`.
In order to build `Goldpinger`, you are going to need `go` version 1.15+ and `docker`.
Building from source code consists of compiling the binary and building a [Docker image](./build/Dockerfile-simple):
Building from source code consists of compiling the binary and building a [Docker image](./Dockerfile):
```sh
# step 0: check out the code
@@ -91,11 +94,10 @@ make bin/goldpinger
./bin/goldpinger --help
# step 2: build the docker image containing the binary
make build
namespace="docker.io/myhandle/" make build
# step 3: push the image somewhere
namespace="docker.io/myhandle/" make tag
namespace="docker.io/myhandle/" make push
docker push $(namespace="docker.io/myhandle/" make version)
```
## Installation
@@ -108,11 +110,15 @@ 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).
```yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: goldpinger-serviceaccount
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
@@ -134,7 +140,7 @@ spec:
labels:
app: goldpinger
spec:
serviceAccount: "goldpinger-serviceaccount"
serviceAccount: goldpinger-serviceaccount
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
@@ -159,7 +165,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: status.podIP
image: "docker.io/bloomberg/goldpinger:2.0.2"
image: "docker.io/bloomberg/goldpinger:v3.0.0"
imagePullPolicy: Always
securityContext:
allowPrivilegeEscalation: false
@@ -207,7 +213,7 @@ Note, that you will also need to add an RBAC rule to allow `Goldpinger` to list
```yaml
---
apiVersion: rbac.authorization.k8s.io/v1beta1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: default
@@ -217,12 +223,18 @@ roleRef:
name: view
subjects:
- kind: ServiceAccount
name: default
name: goldpinger-serviceaccount
namespace: default
```
You can also see [an example of using `kubeconfig` in the `./extras`](./extras/example-with-kubeconfig.yaml).
### Using with IPv4/IPv6 dual-stack
If your cluster IPv4/IPv6 dual-stack and you want to force IPv6, you can set the `IP_VERSIONS` environment variable to "6" (default is "4") which will use the IPv6 address on the pod and host.
![ipv6](./extras/screenshot-ipv6.png)
### 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.
@@ -244,6 +256,27 @@ and `goldpinger` should show something like this:
![screenshot-DNS-resolution](./extras/dns-screenshot.png)
### TCP and HTTP checks to external targets
Instances can also be configured to do simple TCP or HTTP checks on external targets. This is useful for visualizing more nuanced connectivity flows.
```sh
--tcp-targets= A list of external targets(<host>:<port> or <ip>:<port>) to attempt a TCP check on (space delimited) [$TCP_TARGETS]
--http-targets= A list of external targets(<http or https>://<url>) to attempt an HTTP{S} check on. A 200 HTTP code is considered successful. (space delimited) [$HTTP_TARGETS]
--tcp-targets-timeout= The timeout for a tcp check on the provided tcp-targets (default: 500) [$TCP_TARGETS_TIMEOUT]
--dns-targets-timeout= The timeout for a tcp check on the provided udp-targets (default: 500) [$DNS_TARGETS_TIMEOUT]
```
```yaml
- name: HTTP_TARGETS
value: http://bloomberg.com
- name: TCP_TARGETS
value: 10.34.5.141:5000 10.34.195.193:6442
```
the timeouts for the TCP, DNS and HTTP checks can be configured via `TCP_TARGETS_TIMEOUT`, `DNS_TARGETS_TIMEOUT` and `HTTP_TARGETS_TIMEOUT` respectively.
![screenshot-tcp-http-checks](./extras/tcp-checks-screenshot.png)
## Usage
@@ -300,6 +333,15 @@ annotations:
Similarly, why not :heart: contribute some amazing alerts for others to use ?
### Chaos Engineering
Goldpinger also makes for a pretty good monitoring tool in when practicing Chaos Engineering. Check out [PowerfulSeal](https://github.com/bloomberg/powerfulseal), if you'd like to do some Chaos Engineering for Kubernetes.
## Authors
Goldpinger was created by [Mikolaj Pawlikowski](https://github.com/seeker89) and ported to Go by Chris Green.
## Contributions
We :heart: contributions.

View File

@@ -1,6 +0,0 @@
FROM scratch
COPY bin/goldpinger /goldpinger
COPY static /static
ENTRYPOINT ["/goldpinger", "--static-file-path", "/static"]

View File

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

View File

@@ -24,18 +24,14 @@ if [ -z "${PKG}" ]; then
echo "PKG must be set"
exit 1
fi
if [ -z "${ARCH}" ]; then
echo "ARCH must be set"
exit 1
fi
if [ -z "${VERSION}" ]; then
echo "VERSION must be set"
exit 1
fi
export CGO_ENABLED=0
export GOARCH="${ARCH}"
export GOOS=${GOOS:-}
export GOARCH="${ARCH:-amd64}"
export GOOS=${GOOS:-linux}
go build \
-ldflags "-X 'main.Version=${VERSION}' -X 'main.Build=`date`'" \

View File

@@ -15,14 +15,19 @@
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"strconv"
"time"
"github.com/go-openapi/loads"
"go.uber.org/zap"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/utils/net"
"github.com/bloomberg/goldpinger/v3/pkg/goldpinger"
"github.com/bloomberg/goldpinger/v3/pkg/restapi"
@@ -35,37 +40,32 @@ var (
Version, Build string
)
func getLogger() *zap.Logger {
func getLogger(zapconfigpath string) (*zap.Logger, error) {
var logger *zap.Logger
var err error
// We haven't parsed flags at this stage and that might be error prone
// so just use an envvar
if debug, err := strconv.ParseBool(os.Getenv("DEBUG")); err == nil && debug {
logger, err = zap.NewDevelopment()
} else {
logger, err = zap.NewProduction()
}
zapconfigJSON, err := ioutil.ReadFile(zapconfigpath)
if err != nil {
panic(err)
return nil, fmt.Errorf("Could not read zap config file: %w", err)
}
zap.ReplaceGlobals(logger)
return logger
var cfg zap.Config
if err := json.Unmarshal(zapconfigJSON, &cfg); err != nil {
return nil, fmt.Errorf("Could not read zap config as json: %w", err)
}
logger, err = cfg.Build()
if err != nil {
return nil, fmt.Errorf("Could not build zap config: %w", err)
}
return logger, nil
}
func main() {
logger := getLogger()
defer logger.Sync()
undo := zap.RedirectStdLog(logger)
defer undo()
logger.Info("Goldpinger", zap.String("version", Version), zap.String("build", Build))
// load embedded swagger file
swaggerSpec, err := loads.Analyzed(restapi.SwaggerJSON, "")
if err != nil {
logger.Error("Coud not parse swagger", zap.Error(err))
log.Fatalf("Could not parse swagger: %v", err)
}
// create new service API
@@ -82,7 +82,7 @@ func main() {
for _, optsGroup := range api.CommandLineOptionsGroups {
_, err := parser.AddGroup(optsGroup.ShortDescription, optsGroup.LongDescription, optsGroup.Options)
if err != nil {
logger.Error("Coud not add flag group", zap.Error(err))
log.Fatalf("Could not add flag group: %v", err)
}
}
@@ -96,6 +96,29 @@ func main() {
os.Exit(code)
}
// Configure logger
logger, err := getLogger(goldpinger.GoldpingerConfig.ZapConfigPath)
if err != nil {
var errDev error
logger, errDev = zap.NewDevelopment()
if errDev != nil {
log.Fatalf("Could not build a development logger: %v", errDev)
}
logger.Warn("Logger could not be built, defaulting to development settings", zap.String("error", fmt.Sprintf("%v", err)))
}
defer logger.Sync()
undo := zap.RedirectStdLog(logger)
defer undo()
logger.Info("Goldpinger", zap.String("version", Version), zap.String("build", Build))
if goldpinger.GoldpingerConfig.Namespace == nil {
goldpinger.GoldpingerConfig.Namespace = &goldpinger.PodNamespace
} else {
logger.Info("Using configured namespace", zap.String("namespace", *goldpinger.GoldpingerConfig.Namespace))
}
// make a kubernetes client
var config *rest.Config
if goldpinger.GoldpingerConfig.KubeConfigPath == "" {
@@ -126,6 +149,33 @@ func main() {
if goldpinger.GoldpingerConfig.PingNumber == 0 {
logger.Info("--ping-number set to 0: pinging all pods")
}
if goldpinger.GoldpingerConfig.IPVersions == nil || len(goldpinger.GoldpingerConfig.IPVersions) == 0 {
logger.Info("IPVersions not set: settings to 4 (IPv4)")
goldpinger.GoldpingerConfig.IPVersions = []string{"4"}
}
if len(goldpinger.GoldpingerConfig.IPVersions) > 1 {
logger.Warn("Multiple IP versions not supported. Will use first version specified as default", zap.Strings("IPVersions", goldpinger.GoldpingerConfig.IPVersions))
}
if goldpinger.GoldpingerConfig.IPVersions[0] != string(net.IPv4) && goldpinger.GoldpingerConfig.IPVersions[0] != string(net.IPv6) {
logger.Error("Unknown IP version specified: expected values are 4 or 6", zap.Strings("IPVersions", goldpinger.GoldpingerConfig.IPVersions))
}
// Handle deprecated flags
if int(goldpinger.GoldpingerConfig.PingTimeout) == 0 {
logger.Warn("ping-timeout-ms is deprecated in favor of ping-timeout and will be removed in the future",
zap.Int64("ping-timeout-ms", goldpinger.GoldpingerConfig.PingTimeoutMs))
goldpinger.GoldpingerConfig.PingTimeout = time.Duration(goldpinger.GoldpingerConfig.PingTimeoutMs) * time.Millisecond
}
if int(goldpinger.GoldpingerConfig.CheckTimeout) == 0 {
logger.Warn("check-timeout-ms is deprecated in favor of check-timeout and will be removed in the future",
zap.Int64("check-timeout-ms", goldpinger.GoldpingerConfig.CheckTimeoutMs))
goldpinger.GoldpingerConfig.CheckTimeout = time.Duration(goldpinger.GoldpingerConfig.CheckTimeoutMs) * time.Millisecond
}
if int(goldpinger.GoldpingerConfig.CheckAllTimeout) == 0 {
logger.Warn("check-all-timeout-ms is deprecated in favor of check-all-timeout will be removed in the future",
zap.Int64("check-all-timeout-ms", goldpinger.GoldpingerConfig.CheckAllTimeoutMs))
goldpinger.GoldpingerConfig.CheckAllTimeout = time.Duration(goldpinger.GoldpingerConfig.CheckAllTimeoutMs) * time.Millisecond
}
server.ConfigureAPI()
goldpinger.StartUpdater()

21
config/zap.json Normal file
View File

@@ -0,0 +1,21 @@
{
"level": "info",
"encoding": "json",
"outputPaths": [
"stdout"
],
"errorOutputPaths": [
"stderr"
],
"initialFields": {
},
"encoderConfig": {
"messageKey": "message",
"levelKey": "level",
"levelEncoder": "lowercase",
"timeKey": "ts",
"timeEncoder": "ISO8601",
"callerKey": "caller",
"callerEncoder": "Short"
}
}

52
docker-bake.hcl Normal file
View File

@@ -0,0 +1,52 @@
# ref: https://docs.docker.com/build/bake/reference/
# ref: https://github.com/docker/metadata-action?tab=readme-ov-file#bake-definition
target "docker-metadata-action" {
tags = ["goldpinger:latest"]
}
group "default" {
targets = ["linux-simple"]
}
group "ci" {
targets = ["linux-simple", "linux-vendor", "windows-nanoserver-ltsc2019", "windows-nanoserver-ltsc2022"]
}
target "linux-simple" {
inherits = ["docker-metadata-action"]
tags = "${formatlist("%s-linux", target.docker-metadata-action.tags)}"
platforms = ["linux/amd64", "linux/arm64"]
target = "simple"
}
target "linux-vendor" {
inherits = ["docker-metadata-action"]
tags = "${formatlist("%s-vendor", target.docker-metadata-action.tags)}"
platforms = ["linux/amd64", "linux/arm64"]
target = "vendor"
}
target "windows-nanoserver-ltsc2019" {
inherits = ["docker-metadata-action"]
tags = "${formatlist("%s-windows-ltsc2019", target.docker-metadata-action.tags)}"
platforms = ["windows/amd64"]
target = "windows"
args = {
WINDOWS_BASE_IMAGE = "mcr.microsoft.com/windows/nanoserver:ltsc2019"
}
}
target "windows-nanoserver-ltsc2022" {
inherits = ["docker-metadata-action"]
tags = "${formatlist("%s-windows-ltsc2022", target.docker-metadata-action.tags)}"
platforms = ["windows/amd64"]
target = "windows"
args = {
WINDOWS_BASE_IMAGE = "mcr.microsoft.com/windows/nanoserver:ltsc2022"
}
}

View File

@@ -1,8 +0,0 @@
#!/bin/sh
docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD" \
&& make tag \
&& make push \
&& make vendor-tag \
&& make vendor-push

View File

@@ -46,7 +46,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: status.podIP
image: "docker.io/bloomberg/goldpinger:2.0.0"
image: "docker.io/bloomberg/goldpinger:v3.0.0"
imagePullPolicy: Always
securityContext:
allowPrivilegeEscalation: false
@@ -102,7 +102,7 @@ rules:
- list
---
apiVersion: rbac.authorization.k8s.io/v1beta1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: goldpinger-clusterrolebinding

View File

@@ -5,19 +5,16 @@ metadata:
name: goldpinger
labels:
app: goldpinger
version: "2.0.0"
spec:
updateStrategy:
type: RollingUpdate
selector:
matchLabels:
app: goldpinger
version: "2.0.0"
template:
metadata:
labels:
app: goldpinger
version: "2.0.0"
spec:
securityContext:
runAsNonRoot: true
@@ -52,7 +49,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: status.podIP
image: "docker.io/bloomberg/goldpinger:2.0.0"
image: "docker.io/bloomberg/goldpinger:v3.0.0"
imagePullPolicy: Always
securityContext:
allowPrivilegeEscalation: false

BIN
extras/screenshot-ipv6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 KiB

115
go.mod
View File

@@ -1,50 +1,79 @@
module github.com/bloomberg/goldpinger/v3
go 1.14
go 1.21
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/go-openapi/errors v0.20.4
github.com/go-openapi/loads v0.21.2
github.com/go-openapi/runtime v0.26.0
github.com/go-openapi/spec v0.20.9
github.com/go-openapi/strfmt v0.21.7
github.com/go-openapi/swag v0.22.4
github.com/go-openapi/validate v0.22.1
github.com/jessevdk/go-flags v1.5.0
github.com/prometheus/client_golang v1.17.0
github.com/stuartnelson3/go-rendezvous v0.2.0
go.uber.org/zap v1.14.1
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
golang.org/x/image v0.0.0-20190220214146-31aff87c08e9
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a // indirect
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d // 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
go.uber.org/zap v1.26.0
golang.org/x/image v0.13.0
golang.org/x/net v0.17.0
k8s.io/api v0.28.3
k8s.io/apimachinery v0.28.3
k8s.io/client-go v0.28.3
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
)
require (
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/analysis v0.21.4 // indirect
github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go.mongodb.org/mongo-driver v1.12.1 // indirect
go.opentelemetry.io/otel v1.19.0 // indirect
go.opentelemetry.io/otel/metric v1.19.0 // indirect
go.opentelemetry.io/otel/trace v1.19.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/oauth2 v0.13.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/term v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/time v0.3.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)

474
go.sum
View File

@@ -1,189 +1,367 @@
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
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/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/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/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/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/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
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/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY=
github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc=
github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo=
github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.20.4 h1:unTcVm6PispJsMECE3zWgvG4xTiKda1LIR5rCRWLG6M=
github.com/go-openapi/errors v0.20.4/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ=
github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA=
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g=
github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro=
github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw=
github.com/go-openapi/runtime v0.26.0 h1:HYOFtG00FM1UvqrcxbEJg/SwvDRvYLQKGhw2zaQjTcc=
github.com/go-openapi/runtime v0.26.0/go.mod h1:QgRGeZwrUcSHdeh4Ka9Glvo0ug1LC5WyE+EV88plZrQ=
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8=
github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg=
github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k=
github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg=
github.com/go-openapi/strfmt v0.21.7 h1:rspiXgNWgeUzhjo1YU01do6qsahtJNByjLVbPLNHb8k=
github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KAzYjclFs3ew=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU=
github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs=
github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk=
github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28=
github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo=
github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk=
github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw=
github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360=
github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg=
github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE=
github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=
github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/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/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-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/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE=
github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM=
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/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/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q=
github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM=
github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/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/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stuartnelson3/go-rendezvous v0.2.0 h1:H5IexrsptBzCMQEjTRrNH20MVXGqpFf1JUCPglaxd6I=
github.com/stuartnelson3/go-rendezvous v0.2.0/go.mod h1:njfgP6zISyRnZ3iQN13NSEILfSNLN4ysxBoGxHs5PJ0=
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo=
go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg=
go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng=
go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8=
go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE=
go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ=
go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=
go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=
go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8=
go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY=
go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM=
go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg=
go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
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/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
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-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/image v0.13.0 h1:3cge/F/QTkNLauhf2QoE9zp+7sr+ZcL4HnoZmdwg9sg=
golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY=
golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/text v0.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=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
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=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
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=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.28.3 h1:Gj1HtbSdB4P08C8rs9AR94MfSGpRhJgsS+GF9V26xMM=
k8s.io/api v0.28.3/go.mod h1:MRCV/jr1dW87/qJnZ57U5Pak65LGmQVkKTzf3AtKFHc=
k8s.io/apimachinery v0.28.3 h1:B1wYx8txOaCQG0HmYF6nbpU8dg6HvA06x5tEffvOe7A=
k8s.io/apimachinery v0.28.3/go.mod h1:uQTKmIqs+rAYaq+DFaoD2X7pcjLOqbQX2AOiO0nIpb8=
k8s.io/client-go v0.28.3 h1:2OqNb72ZuTZPKCl+4gTKvqao0AMOl9f3o2ijbAj3LI4=
k8s.io/client-go v0.28.3/go.mod h1:LTykbBp9gsA7SwqirlCXBWtK0guzfhpoW4qSm7i9dxo=
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk=
sigs.k8s.io/structured-merge-diff/v4 v4.3.0/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=

View File

@@ -16,47 +16,46 @@ import (
"github.com/go-openapi/strfmt"
)
// NewCheckAllPodsParams creates a new CheckAllPodsParams object
// with the default values initialized.
// NewCheckAllPodsParams creates a new CheckAllPodsParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewCheckAllPodsParams() *CheckAllPodsParams {
return &CheckAllPodsParams{
timeout: cr.DefaultTimeout,
}
}
// NewCheckAllPodsParamsWithTimeout creates a new CheckAllPodsParams object
// with the default values initialized, and the ability to set a timeout on a request
// with the ability to set a timeout on a request.
func NewCheckAllPodsParamsWithTimeout(timeout time.Duration) *CheckAllPodsParams {
return &CheckAllPodsParams{
timeout: timeout,
}
}
// NewCheckAllPodsParamsWithContext creates a new CheckAllPodsParams object
// with the default values initialized, and the ability to set a context for a request
// with the ability to set a context for a request.
func NewCheckAllPodsParamsWithContext(ctx context.Context) *CheckAllPodsParams {
return &CheckAllPodsParams{
Context: ctx,
}
}
// NewCheckAllPodsParamsWithHTTPClient creates a new CheckAllPodsParams object
// with the default values initialized, and the ability to set a custom HTTPClient for a request
// with the ability to set a custom HTTPClient for a request.
func NewCheckAllPodsParamsWithHTTPClient(client *http.Client) *CheckAllPodsParams {
return &CheckAllPodsParams{
HTTPClient: client,
}
}
/*CheckAllPodsParams contains all the parameters to send to the API endpoint
for the check all pods operation typically these are written to a http.Request
/* CheckAllPodsParams contains all the parameters to send to the API endpoint
for the check all pods operation.
Typically these are written to a http.Request.
*/
type CheckAllPodsParams struct {
timeout time.Duration
@@ -64,6 +63,21 @@ type CheckAllPodsParams struct {
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the check all pods params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *CheckAllPodsParams) WithDefaults() *CheckAllPodsParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the check all pods params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *CheckAllPodsParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the check all pods params
func (o *CheckAllPodsParams) WithTimeout(timeout time.Duration) *CheckAllPodsParams {
o.SetTimeout(timeout)

View File

@@ -29,9 +29,8 @@ func (o *CheckAllPodsReader) ReadResponse(response runtime.ClientResponse, consu
return nil, err
}
return result, nil
default:
return nil, runtime.NewAPIError("unknown error", response, response.Code())
return nil, runtime.NewAPIError("response status code does not match any response statuses defined for this endpoint in the swagger spec", response, response.Code())
}
}
@@ -40,7 +39,7 @@ func NewCheckAllPodsOK() *CheckAllPodsOK {
return &CheckAllPodsOK{}
}
/*CheckAllPodsOK handles this case with default header values.
/* CheckAllPodsOK describes a response with status code 200, with default header values.
Success, return response
*/
@@ -51,7 +50,6 @@ type CheckAllPodsOK struct {
func (o *CheckAllPodsOK) Error() string {
return fmt.Sprintf("[GET /check_all][%d] checkAllPodsOK %+v", 200, o.Payload)
}
func (o *CheckAllPodsOK) GetPayload() *models.CheckAllResults {
return o.Payload
}

View File

@@ -16,47 +16,46 @@ import (
"github.com/go-openapi/strfmt"
)
// NewCheckServicePodsParams creates a new CheckServicePodsParams object
// with the default values initialized.
// NewCheckServicePodsParams creates a new CheckServicePodsParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewCheckServicePodsParams() *CheckServicePodsParams {
return &CheckServicePodsParams{
timeout: cr.DefaultTimeout,
}
}
// NewCheckServicePodsParamsWithTimeout creates a new CheckServicePodsParams object
// with the default values initialized, and the ability to set a timeout on a request
// with the ability to set a timeout on a request.
func NewCheckServicePodsParamsWithTimeout(timeout time.Duration) *CheckServicePodsParams {
return &CheckServicePodsParams{
timeout: timeout,
}
}
// NewCheckServicePodsParamsWithContext creates a new CheckServicePodsParams object
// with the default values initialized, and the ability to set a context for a request
// with the ability to set a context for a request.
func NewCheckServicePodsParamsWithContext(ctx context.Context) *CheckServicePodsParams {
return &CheckServicePodsParams{
Context: ctx,
}
}
// NewCheckServicePodsParamsWithHTTPClient creates a new CheckServicePodsParams object
// with the default values initialized, and the ability to set a custom HTTPClient for a request
// with the ability to set a custom HTTPClient for a request.
func NewCheckServicePodsParamsWithHTTPClient(client *http.Client) *CheckServicePodsParams {
return &CheckServicePodsParams{
HTTPClient: client,
}
}
/*CheckServicePodsParams contains all the parameters to send to the API endpoint
for the check service pods operation typically these are written to a http.Request
/* CheckServicePodsParams contains all the parameters to send to the API endpoint
for the check service pods operation.
Typically these are written to a http.Request.
*/
type CheckServicePodsParams struct {
timeout time.Duration
@@ -64,6 +63,21 @@ type CheckServicePodsParams struct {
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the check service pods params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *CheckServicePodsParams) WithDefaults() *CheckServicePodsParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the check service pods params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *CheckServicePodsParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the check service pods params
func (o *CheckServicePodsParams) WithTimeout(timeout time.Duration) *CheckServicePodsParams {
o.SetTimeout(timeout)

View File

@@ -29,9 +29,8 @@ func (o *CheckServicePodsReader) ReadResponse(response runtime.ClientResponse, c
return nil, err
}
return result, nil
default:
return nil, runtime.NewAPIError("unknown error", response, response.Code())
return nil, runtime.NewAPIError("response status code does not match any response statuses defined for this endpoint in the swagger spec", response, response.Code())
}
}
@@ -40,7 +39,7 @@ func NewCheckServicePodsOK() *CheckServicePodsOK {
return &CheckServicePodsOK{}
}
/*CheckServicePodsOK handles this case with default header values.
/* CheckServicePodsOK describes a response with status code 200, with default header values.
Success, return response
*/
@@ -51,7 +50,6 @@ type CheckServicePodsOK struct {
func (o *CheckServicePodsOK) Error() string {
return fmt.Sprintf("[GET /check][%d] checkServicePodsOK %+v", 200, o.Payload)
}
func (o *CheckServicePodsOK) GetPayload() *models.CheckResults {
return o.Payload
}

View File

@@ -0,0 +1,126 @@
// Code generated by go-swagger; DO NOT EDIT.
package operations
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
// NewClusterHealthParams creates a new ClusterHealthParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewClusterHealthParams() *ClusterHealthParams {
return &ClusterHealthParams{
timeout: cr.DefaultTimeout,
}
}
// NewClusterHealthParamsWithTimeout creates a new ClusterHealthParams object
// with the ability to set a timeout on a request.
func NewClusterHealthParamsWithTimeout(timeout time.Duration) *ClusterHealthParams {
return &ClusterHealthParams{
timeout: timeout,
}
}
// NewClusterHealthParamsWithContext creates a new ClusterHealthParams object
// with the ability to set a context for a request.
func NewClusterHealthParamsWithContext(ctx context.Context) *ClusterHealthParams {
return &ClusterHealthParams{
Context: ctx,
}
}
// NewClusterHealthParamsWithHTTPClient creates a new ClusterHealthParams object
// with the ability to set a custom HTTPClient for a request.
func NewClusterHealthParamsWithHTTPClient(client *http.Client) *ClusterHealthParams {
return &ClusterHealthParams{
HTTPClient: client,
}
}
/* ClusterHealthParams contains all the parameters to send to the API endpoint
for the cluster health operation.
Typically these are written to a http.Request.
*/
type ClusterHealthParams struct {
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the cluster health params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *ClusterHealthParams) WithDefaults() *ClusterHealthParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the cluster health params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *ClusterHealthParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the cluster health params
func (o *ClusterHealthParams) WithTimeout(timeout time.Duration) *ClusterHealthParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the cluster health params
func (o *ClusterHealthParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the cluster health params
func (o *ClusterHealthParams) WithContext(ctx context.Context) *ClusterHealthParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the cluster health params
func (o *ClusterHealthParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the cluster health params
func (o *ClusterHealthParams) WithHTTPClient(client *http.Client) *ClusterHealthParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the cluster health params
func (o *ClusterHealthParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WriteToRequest writes these params to a swagger request
func (o *ClusterHealthParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -0,0 +1,105 @@
// Code generated by go-swagger; DO NOT EDIT.
package operations
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
"github.com/bloomberg/goldpinger/v3/pkg/models"
)
// ClusterHealthReader is a Reader for the ClusterHealth structure.
type ClusterHealthReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *ClusterHealthReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewClusterHealthOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 418:
result := NewClusterHealthIMATeapot()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("response status code does not match any response statuses defined for this endpoint in the swagger spec", response, response.Code())
}
}
// NewClusterHealthOK creates a ClusterHealthOK with default headers values
func NewClusterHealthOK() *ClusterHealthOK {
return &ClusterHealthOK{}
}
/* ClusterHealthOK describes a response with status code 200, with default header values.
Healthy cluster
*/
type ClusterHealthOK struct {
Payload *models.ClusterHealthResults
}
func (o *ClusterHealthOK) Error() string {
return fmt.Sprintf("[GET /cluster_health][%d] clusterHealthOK %+v", 200, o.Payload)
}
func (o *ClusterHealthOK) GetPayload() *models.ClusterHealthResults {
return o.Payload
}
func (o *ClusterHealthOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(models.ClusterHealthResults)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewClusterHealthIMATeapot creates a ClusterHealthIMATeapot with default headers values
func NewClusterHealthIMATeapot() *ClusterHealthIMATeapot {
return &ClusterHealthIMATeapot{}
}
/* ClusterHealthIMATeapot describes a response with status code 418, with default header values.
Unhealthy cluster
*/
type ClusterHealthIMATeapot struct {
Payload *models.ClusterHealthResults
}
func (o *ClusterHealthIMATeapot) Error() string {
return fmt.Sprintf("[GET /cluster_health][%d] clusterHealthIMATeapot %+v", 418, o.Payload)
}
func (o *ClusterHealthIMATeapot) GetPayload() *models.ClusterHealthResults {
return o.Payload
}
func (o *ClusterHealthIMATeapot) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(models.ClusterHealthResults)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View File

@@ -16,47 +16,46 @@ import (
"github.com/go-openapi/strfmt"
)
// NewHealthzParams creates a new HealthzParams object
// with the default values initialized.
// NewHealthzParams creates a new HealthzParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewHealthzParams() *HealthzParams {
return &HealthzParams{
timeout: cr.DefaultTimeout,
}
}
// NewHealthzParamsWithTimeout creates a new HealthzParams object
// with the default values initialized, and the ability to set a timeout on a request
// with the ability to set a timeout on a request.
func NewHealthzParamsWithTimeout(timeout time.Duration) *HealthzParams {
return &HealthzParams{
timeout: timeout,
}
}
// NewHealthzParamsWithContext creates a new HealthzParams object
// with the default values initialized, and the ability to set a context for a request
// with the ability to set a context for a request.
func NewHealthzParamsWithContext(ctx context.Context) *HealthzParams {
return &HealthzParams{
Context: ctx,
}
}
// NewHealthzParamsWithHTTPClient creates a new HealthzParams object
// with the default values initialized, and the ability to set a custom HTTPClient for a request
// with the ability to set a custom HTTPClient for a request.
func NewHealthzParamsWithHTTPClient(client *http.Client) *HealthzParams {
return &HealthzParams{
HTTPClient: client,
}
}
/*HealthzParams contains all the parameters to send to the API endpoint
for the healthz operation typically these are written to a http.Request
/* HealthzParams contains all the parameters to send to the API endpoint
for the healthz operation.
Typically these are written to a http.Request.
*/
type HealthzParams struct {
timeout time.Duration
@@ -64,6 +63,21 @@ type HealthzParams struct {
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the healthz params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *HealthzParams) WithDefaults() *HealthzParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the healthz params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *HealthzParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the healthz params
func (o *HealthzParams) WithTimeout(timeout time.Duration) *HealthzParams {
o.SetTimeout(timeout)

View File

@@ -35,9 +35,8 @@ func (o *HealthzReader) ReadResponse(response runtime.ClientResponse, consumer r
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("unknown error", response, response.Code())
return nil, runtime.NewAPIError("response status code does not match any response statuses defined for this endpoint in the swagger spec", response, response.Code())
}
}
@@ -46,7 +45,7 @@ func NewHealthzOK() *HealthzOK {
return &HealthzOK{}
}
/*HealthzOK handles this case with default header values.
/* HealthzOK describes a response with status code 200, with default header values.
Health check report
*/
@@ -57,7 +56,6 @@ type HealthzOK struct {
func (o *HealthzOK) Error() string {
return fmt.Sprintf("[GET /healthz][%d] healthzOK %+v", 200, o.Payload)
}
func (o *HealthzOK) GetPayload() *models.HealthCheckResults {
return o.Payload
}
@@ -79,7 +77,7 @@ func NewHealthzServiceUnavailable() *HealthzServiceUnavailable {
return &HealthzServiceUnavailable{}
}
/*HealthzServiceUnavailable handles this case with default header values.
/* HealthzServiceUnavailable describes a response with status code 503, with default header values.
Unhealthy service
*/
@@ -90,7 +88,6 @@ type HealthzServiceUnavailable struct {
func (o *HealthzServiceUnavailable) Error() string {
return fmt.Sprintf("[GET /healthz][%d] healthzServiceUnavailable %+v", 503, o.Payload)
}
func (o *HealthzServiceUnavailable) GetPayload() *models.HealthCheckResults {
return o.Payload
}

View File

@@ -25,15 +25,20 @@ type Client struct {
formats strfmt.Registry
}
// ClientOption is the option for Client methods
type ClientOption func(*runtime.ClientOperation)
// ClientService is the interface for Client methods
type ClientService interface {
CheckAllPods(params *CheckAllPodsParams) (*CheckAllPodsOK, error)
CheckAllPods(params *CheckAllPodsParams, opts ...ClientOption) (*CheckAllPodsOK, error)
CheckServicePods(params *CheckServicePodsParams) (*CheckServicePodsOK, error)
CheckServicePods(params *CheckServicePodsParams, opts ...ClientOption) (*CheckServicePodsOK, error)
Healthz(params *HealthzParams) (*HealthzOK, error)
ClusterHealth(params *ClusterHealthParams, opts ...ClientOption) (*ClusterHealthOK, error)
Ping(params *PingParams) (*PingOK, error)
Healthz(params *HealthzParams, opts ...ClientOption) (*HealthzOK, error)
Ping(params *PingParams, opts ...ClientOption) (*PingOK, error)
SetTransport(transport runtime.ClientTransport)
}
@@ -41,13 +46,12 @@ type ClientService interface {
/*
CheckAllPods Queries the API server for all other pods in this service, and makes all of them query all of their neighbours, using their pods IPs. Calls their /check endpoint.
*/
func (a *Client) CheckAllPods(params *CheckAllPodsParams) (*CheckAllPodsOK, error) {
func (a *Client) CheckAllPods(params *CheckAllPodsParams, opts ...ClientOption) (*CheckAllPodsOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewCheckAllPodsParams()
}
result, err := a.transport.Submit(&runtime.ClientOperation{
op := &runtime.ClientOperation{
ID: "checkAllPods",
Method: "GET",
PathPattern: "/check_all",
@@ -58,7 +62,12 @@ func (a *Client) CheckAllPods(params *CheckAllPodsParams) (*CheckAllPodsOK, erro
Reader: &CheckAllPodsReader{formats: a.formats},
Context: params.Context,
Client: params.HTTPClient,
})
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
@@ -75,13 +84,12 @@ func (a *Client) CheckAllPods(params *CheckAllPodsParams) (*CheckAllPodsOK, erro
/*
CheckServicePods Queries the API server for all other pods in this service, and pings them via their pods IPs. Calls their /ping endpoint
*/
func (a *Client) CheckServicePods(params *CheckServicePodsParams) (*CheckServicePodsOK, error) {
func (a *Client) CheckServicePods(params *CheckServicePodsParams, opts ...ClientOption) (*CheckServicePodsOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewCheckServicePodsParams()
}
result, err := a.transport.Submit(&runtime.ClientOperation{
op := &runtime.ClientOperation{
ID: "checkServicePods",
Method: "GET",
PathPattern: "/check",
@@ -92,7 +100,12 @@ func (a *Client) CheckServicePods(params *CheckServicePodsParams) (*CheckService
Reader: &CheckServicePodsReader{formats: a.formats},
Context: params.Context,
Client: params.HTTPClient,
})
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
@@ -106,16 +119,53 @@ func (a *Client) CheckServicePods(params *CheckServicePodsParams) (*CheckService
panic(msg)
}
/*
ClusterHealth Checks the full graph. Returns a binary OK or not OK.
*/
func (a *Client) ClusterHealth(params *ClusterHealthParams, opts ...ClientOption) (*ClusterHealthOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewClusterHealthParams()
}
op := &runtime.ClientOperation{
ID: "clusterHealth",
Method: "GET",
PathPattern: "/cluster_health",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &ClusterHealthReader{formats: a.formats},
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*ClusterHealthOK)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for clusterHealth: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/*
Healthz The healthcheck endpoint provides detailed information about the health of a web service. If each of the components required by the service are healthy, then the service is considered healthy and will return a 200 OK response. If any of the components needed by the service are unhealthy, then a 503 Service Unavailable response will be provided.
*/
func (a *Client) Healthz(params *HealthzParams) (*HealthzOK, error) {
func (a *Client) Healthz(params *HealthzParams, opts ...ClientOption) (*HealthzOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewHealthzParams()
}
result, err := a.transport.Submit(&runtime.ClientOperation{
op := &runtime.ClientOperation{
ID: "healthz",
Method: "GET",
PathPattern: "/healthz",
@@ -126,7 +176,12 @@ func (a *Client) Healthz(params *HealthzParams) (*HealthzOK, error) {
Reader: &HealthzReader{formats: a.formats},
Context: params.Context,
Client: params.HTTPClient,
})
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
@@ -143,13 +198,12 @@ func (a *Client) Healthz(params *HealthzParams) (*HealthzOK, error) {
/*
Ping return query stats
*/
func (a *Client) Ping(params *PingParams) (*PingOK, error) {
func (a *Client) Ping(params *PingParams, opts ...ClientOption) (*PingOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewPingParams()
}
result, err := a.transport.Submit(&runtime.ClientOperation{
op := &runtime.ClientOperation{
ID: "ping",
Method: "GET",
PathPattern: "/ping",
@@ -160,7 +214,12 @@ func (a *Client) Ping(params *PingParams) (*PingOK, error) {
Reader: &PingReader{formats: a.formats},
Context: params.Context,
Client: params.HTTPClient,
})
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}

View File

@@ -16,47 +16,46 @@ import (
"github.com/go-openapi/strfmt"
)
// NewPingParams creates a new PingParams object
// with the default values initialized.
// NewPingParams creates a new PingParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewPingParams() *PingParams {
return &PingParams{
timeout: cr.DefaultTimeout,
}
}
// NewPingParamsWithTimeout creates a new PingParams object
// with the default values initialized, and the ability to set a timeout on a request
// with the ability to set a timeout on a request.
func NewPingParamsWithTimeout(timeout time.Duration) *PingParams {
return &PingParams{
timeout: timeout,
}
}
// NewPingParamsWithContext creates a new PingParams object
// with the default values initialized, and the ability to set a context for a request
// with the ability to set a context for a request.
func NewPingParamsWithContext(ctx context.Context) *PingParams {
return &PingParams{
Context: ctx,
}
}
// NewPingParamsWithHTTPClient creates a new PingParams object
// with the default values initialized, and the ability to set a custom HTTPClient for a request
// with the ability to set a custom HTTPClient for a request.
func NewPingParamsWithHTTPClient(client *http.Client) *PingParams {
return &PingParams{
HTTPClient: client,
}
}
/*PingParams contains all the parameters to send to the API endpoint
for the ping operation typically these are written to a http.Request
/* PingParams contains all the parameters to send to the API endpoint
for the ping operation.
Typically these are written to a http.Request.
*/
type PingParams struct {
timeout time.Duration
@@ -64,6 +63,21 @@ type PingParams struct {
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the ping params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *PingParams) WithDefaults() *PingParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the ping params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *PingParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the ping params
func (o *PingParams) WithTimeout(timeout time.Duration) *PingParams {
o.SetTimeout(timeout)

View File

@@ -29,9 +29,8 @@ func (o *PingReader) ReadResponse(response runtime.ClientResponse, consumer runt
return nil, err
}
return result, nil
default:
return nil, runtime.NewAPIError("unknown error", response, response.Code())
return nil, runtime.NewAPIError("response status code does not match any response statuses defined for this endpoint in the swagger spec", response, response.Code())
}
}
@@ -40,7 +39,7 @@ func NewPingOK() *PingOK {
return &PingOK{}
}
/*PingOK handles this case with default header values.
/* PingOK describes a response with status code 200, with default header values.
return success
*/
@@ -51,7 +50,6 @@ type PingOK struct {
func (o *PingOK) Error() string {
return fmt.Sprintf("[GET /ping][%d] pingOK %+v", 200, o.Payload)
}
func (o *PingOK) GetPayload() *models.PingResults {
return o.Payload
}

View File

@@ -17,8 +17,9 @@ package goldpinger
import (
"context"
"errors"
"fmt"
"net"
"sort"
"strconv"
"sync"
"time"
@@ -36,15 +37,12 @@ func CheckNeighbours(ctx context.Context) *models.CheckResults {
// Mux to prevent concurrent map address
checkResultsMux.Lock()
defer checkResultsMux.Unlock()
final := models.CheckResults{}
final.PodResults = make(map[string]models.PodResult)
for podName, podResult := range checkResults.PodResults {
final.PodResults[podName] = podResult
}
if len(GoldpingerConfig.DnsHosts) > 0 {
final.DNSResults = *checkDNS()
}
final.ProbeResults = checkTargets()
return &final
}
@@ -54,6 +52,65 @@ func CheckNeighboursNeighbours(ctx context.Context) *models.CheckAllResults {
return CheckAllPods(ctx, SelectPods())
}
// CheckCluster does a CheckNeighboursNeighbours and analyses results to produce a binary OK or not OK
func CheckCluster(ctx context.Context) *models.ClusterHealthResults {
start := time.Now()
output := models.ClusterHealthResults{
GeneratedAt: strfmt.DateTime(start),
OK: true,
}
selectedPods := SelectPods()
// precompute the expected set of nodes
expectedNodes := []string{}
for _, peer := range selectedPods {
expectedNodes = append(expectedNodes, peer.HostIP)
}
sort.Strings(expectedNodes)
// get the response we serve for check_all
checkAll := CheckAllPods(ctx, selectedPods)
// we should at the very least have a response from ourselves
if len(checkAll.Responses) < 1 {
output.OK = false
}
for _, resp := range checkAll.Responses {
// 1. check that all nodes report OK
if *resp.OK {
output.NodesHealthy = append(output.NodesHealthy, resp.HostIP.String())
} else {
output.NodesUnhealthy = append(output.NodesUnhealthy, resp.HostIP.String())
output.OK = false
}
output.NodesTotal++
// 2. check that all nodes report the expected peers
// on error, there might be no response from the node
if resp.Response == nil {
output.OK = false
continue
}
// if we get a response, let's check we get the expected nodes
observedNodes := []string{}
for _, peer := range resp.Response.PodResults {
observedNodes = append(observedNodes, string(peer.HostIP))
}
sort.Strings(observedNodes)
if len(observedNodes) != len(expectedNodes) {
output.OK = false
}
for i, val := range observedNodes {
if val != expectedNodes[i] {
output.OK = false
break
}
}
}
output.DurationNs = time.Since(start).Nanoseconds()
return &output
}
// PingAllPodsResult holds results from pinging all nodes
type PingAllPodsResult struct {
podName string
podResult models.PodResult
@@ -67,24 +124,61 @@ func pickPodHostIP(podIP, hostIP string) string {
return podIP
}
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
func checkTargets() models.ProbeResults {
results := make(map[string][]models.ProbeResult)
probes := []struct {
protocol string
hosts []string
probeFn func(addr string, timeout time.Duration) error
statFn func(host string)
timeout time.Duration
}{
{
protocol: "dns",
hosts: GoldpingerConfig.DnsHosts,
probeFn: doDNSProbe,
statFn: CountDnsError,
timeout: GoldpingerConfig.DnsCheckTimeout,
},
{
protocol: "http",
hosts: GoldpingerConfig.HTTPTargets,
probeFn: doHTTPProbe,
statFn: CountHttpError,
timeout: GoldpingerConfig.HTTPCheckTimeout,
},
{
protocol: "tcp",
hosts: GoldpingerConfig.TCPTargets,
probeFn: doTCPProbe,
statFn: CountTcpError,
timeout: GoldpingerConfig.TCPCheckTimeout,
},
}
return &results
for _, probe := range probes {
for _, host := range probe.hosts {
if _, ok := results[host]; !ok {
results[host] = []models.ProbeResult{}
}
res := models.ProbeResult{Protocol: probe.protocol}
start := time.Now()
err := probe.probeFn(host, probe.timeout)
if err != nil {
res.Error = err.Error()
probe.statFn(host)
}
res.ResponseTimeMs = time.Since(start).Milliseconds()
results[host] = append(results[host], res)
}
}
return results
}
// CheckServicePodsResult results of the /check operation
type CheckServicePodsResult struct {
podName string
checkAllPodResult models.CheckAllPodResult
@@ -92,8 +186,8 @@ type CheckServicePodsResult struct {
podIPv4 strfmt.IPv4
}
// CheckAllPods calls all neighbours and returns a detailed report
func CheckAllPods(checkAllCtx context.Context, pods map[string]*GoldpingerPod) *models.CheckAllResults {
result := models.CheckAllResults{Responses: make(map[string]models.CheckAllPodResult)}
ch := make(chan CheckServicePodsResult, len(pods))
@@ -101,9 +195,7 @@ func CheckAllPods(checkAllCtx context.Context, pods map[string]*GoldpingerPod) *
wg.Add(len(pods))
for _, pod := range pods {
go func(pod *GoldpingerPod) {
// logger
logger := zap.L().With(
zap.String("op", "check"),
@@ -136,7 +228,7 @@ func CheckAllPods(checkAllCtx context.Context, pods map[string]*GoldpingerPod) *
} else {
checkCtx, cancel := context.WithTimeout(
checkAllCtx,
time.Duration(GoldpingerConfig.CheckTimeoutMs)*time.Millisecond,
GoldpingerConfig.CheckTimeout,
)
defer cancel()
@@ -179,21 +271,22 @@ func CheckAllPods(checkAllCtx context.Context, pods map[string]*GoldpingerPod) *
PodIP: response.podIPv4,
})
if response.checkAllPodResult.Response != nil &&
response.checkAllPodResult.Response.DNSResults != nil {
if result.DNSResults == nil {
result.DNSResults = make(map[string]models.DNSResults)
response.checkAllPodResult.Response.ProbeResults != nil {
if result.ProbeResults == nil {
result.ProbeResults = make(map[string]models.ProbeResults)
}
for host := range response.checkAllPodResult.Response.DNSResults {
if result.DNSResults[host] == nil {
result.DNSResults[host] = make(map[string]models.DNSResult)
for host := range response.checkAllPodResult.Response.ProbeResults {
if result.ProbeResults[host] == nil {
result.ProbeResults[host] = make(map[string][]models.ProbeResult)
}
result.DNSResults[host][response.podName] = response.checkAllPodResult.Response.DNSResults[host]
result.ProbeResults[host][response.podName] = response.checkAllPodResult.Response.ProbeResults[host]
}
}
}
return &result
}
// HealthCheck returns a simple 200 OK response to verify the API is up
func HealthCheck() *models.HealthCheckResults {
ok := true
start := time.Now()
@@ -209,7 +302,7 @@ 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)
host := net.JoinHostPort(hostIP, strconv.Itoa(GoldpingerConfig.Port))
transport := httptransport.New(host, "", nil)
client := apiclient.New(transport, strfmt.Default)
apiclient.Default.SetTransport(transport)

View File

@@ -15,28 +15,43 @@
package goldpinger
import (
"time"
"k8s.io/client-go/kubernetes"
)
// GoldpingerConfig represents the configuration for goldpinger
var GoldpingerConfig = struct {
StaticFilePath string `long:"static-file-path" description:"Folder for serving static files" env:"STATIC_FILE_PATH"`
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"`
StaticFilePath string `long:"static-file-path" description:"Folder for serving static files" env:"STATIC_FILE_PATH"`
ZapConfigPath string `long:"zap-config" description:"Path to zap config file" env:"ZAP_CONFIG" default:"/config/zap.json"`
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"`
JitterFactor float64 `long:"jitter-factor" description:"The amount of jitter to add while pinging clients" env:"JITTER_FACTOR" default:"0.05"`
Hostname string `long:"hostname" description:"Hostname to use" env:"HOSTNAME"`
PodIP string `long:"pod-ip" description:"Pod IP to use" env:"POD_IP"`
PodName string `long:"pod-name" description:"The name of this pod - used to select --ping-number of pods using rendezvous hashing" env:"POD_NAME"`
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"`
Hostname string `long:"hostname" description:"Hostname to use" env:"HOSTNAME"`
PodIP string `long:"pod-ip" description:"Pod IP to use" env:"POD_IP"`
PodName string `long:"pod-name" description:"The name of this pod - used to select --ping-number of pods using rendezvous hashing" env:"POD_NAME"`
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"`
Namespace *string `long:"namespace" description:"namespace to use to discover goldpinger pods in the cluster (empty for all). Defaults to discovering the namespace for the current pod" env:"NAMESPACE"`
DisplayNodeName bool `long:"display-nodename" description:"Display nodename other than podname in UI (defaults is podname)." env:"DISPLAY_NODENAME"`
KubernetesClient *kubernetes.Clientset
DnsHosts []string `long:"host-to-resolve" description:"A host to attempt dns resolve on (space delimited)" env:"HOSTS_TO_RESOLVE" env-delim:" "`
DnsHosts []string `long:"host-to-resolve" description:"A host to attempt dns resolve on (space delimited)" env:"HOSTS_TO_RESOLVE" env-delim:" "`
TCPTargets []string `long:"tcp-targets" description:"A list of external targets(<host>:<port> or <ip>:<port>) to attempt a TCP check on (space delimited)" env:"TCP_TARGETS" env-delim:" "`
HTTPTargets []string `long:"http-targets" description:"A list of external targets(<http or https>://<url>) to attempt an HTTP{S} check on. A 200 HTTP code is considered successful.(space delimited)" env:"HTTP_TARGETS" env-delim:" "`
IPVersions []string `long:"ip-versions" description:"The IP versions to use (space delimited). Possible values are 4 and 6 (defaults to 4)." env:"IP_VERSIONS" env-delim:" "`
// Timeouts
PingTimeoutMs int64 `long:"ping-timeout-ms" description:"The timeout in milliseconds for a ping call to other goldpinger pods" env:"PING_TIMEOUT_MS" default:"300"`
CheckTimeoutMs int64 `long:"check-timeout-ms" description:"The timeout in milliseconds for a check call to other goldpinger pods" env:"CHECK_TIMEOUT_MS" default:"1000"`
CheckAllTimeoutMs int64 `long:"check-all-timeout-ms" description:"The timeout in milliseconds for a check-all call to other goldpinger pods" env:"CHECK_ALL_TIMEOUT_MS" default:"5000"`
PingTimeoutMs int64 `long:"ping-timeout-ms" description:"The timeout in milliseconds for a ping call to other goldpinger pods(deprecated)" env:"PING_TIMEOUT_MS" default:"300"`
CheckTimeoutMs int64 `long:"check-timeout-ms" description:"The timeout in milliseconds for a check call to other goldpinger pods(deprecated)" env:"CHECK_TIMEOUT_MS" default:"1000"`
CheckAllTimeoutMs int64 `long:"check-all-timeout-ms" description:"The timeout in milliseconds for a check-all call to other goldpinger pods(deprecated)" env:"CHECK_ALL_TIMEOUT_MS" default:"5000"`
PingTimeout time.Duration `long:"ping-timeout" description:"The timeout for a ping call to other goldpinger pods" env:"PING_TIMEOUT" default:"300ms"`
CheckTimeout time.Duration `long:"check-timeout" description:"The timeout for a check call to other goldpinger pods" env:"CHECK_TIMEOUT" default:"1000ms"`
CheckAllTimeout time.Duration `long:"check-all-timeout" description:"The timeout for a check-all call to other goldpinger pods" env:"CHECK_ALL_TIMEOUT" default:"5000ms"`
TCPCheckTimeout time.Duration `long:"tcp-targets-timeout" description:"The timeout for a tcp check on the provided tcp-targets" env:"TCP_TARGETS_TIMEOUT" default:"500ms"`
DnsCheckTimeout time.Duration `long:"dns-targets-timeout" description:"The timeout for a dns check on the provided dns-targets" env:"DNS_TARGETS_TIMEOUT" default:"500ms"`
HTTPCheckTimeout time.Duration `long:"http-targets-timeout" description:"The timeout for a http check on the provided http-targets" env:"HTTP_TARGETS_TIMEOUT" default:"500ms"`
}{}

View File

@@ -26,7 +26,6 @@ import (
"net/http"
"sort"
"strconv"
"time"
"go.uber.org/zap"
"golang.org/x/image/font"
@@ -83,7 +82,7 @@ func HeatmapHandler(w http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(
r.Context(),
time.Duration(GoldpingerConfig.CheckAllTimeoutMs)*time.Millisecond,
GoldpingerConfig.CheckAllTimeout,
)
defer cancel()

View File

@@ -15,14 +15,19 @@
package goldpinger
import (
"context"
"io/ioutil"
"go.uber.org/zap"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8snet "k8s.io/utils/net"
)
// namespace is the namespace for the goldpinger pod
var namespace = getNamespace()
var nodeIPMap = make(map[string]string)
// PodNamespace is the auto-detected namespace for this goldpinger pod
var PodNamespace = getPodNamespace()
// GoldpingerPod contains just the basic info needed to ping and keep track of a given goldpinger pod
type GoldpingerPod struct {
@@ -31,7 +36,7 @@ type GoldpingerPod struct {
HostIP string // HostIP is the IP address of the host where the pod lives
}
func getNamespace() string {
func getPodNamespace() string {
b, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
if err != nil {
zap.L().Warn("Unable to determine namespace", zap.Error(err))
@@ -41,10 +46,71 @@ func getNamespace() string {
return namespace
}
// getHostIP gets the IP of the host where the pod is scheduled. If UseIPv6 is enabled then we need to check
// the node IPs since HostIP will only list the default IP version one.
func getHostIP(p v1.Pod) string {
if ipMatchesConfig(p.Status.HostIP) {
return p.Status.HostIP
}
if addr, ok := nodeIPMap[p.Spec.NodeName]; ok {
return addr
}
timer := GetLabeledKubernetesCallsTimer()
node, err := GoldpingerConfig.KubernetesClient.CoreV1().Nodes().Get(context.TODO(), p.Spec.NodeName, metav1.GetOptions{})
if err != nil {
zap.L().Error("error getting node", zap.Error(err))
CountError("kubernetes_api")
return p.Status.HostIP
} else {
timer.ObserveDuration()
}
var hostIP string
for _, addr := range node.Status.Addresses {
if (addr.Type == v1.NodeInternalIP || addr.Type == v1.NodeExternalIP) &&
ipMatchesConfig(addr.Address) {
hostIP = addr.Address
}
}
nodeIPMap[p.Spec.NodeName] = hostIP
return hostIP
}
// getPodIP will get an IPv6 IP from PodIPs if the UseIPv6 config is set, otherwise just return the object PodIP
func getPodIP(p v1.Pod) string {
if ipMatchesConfig(p.Status.PodIP) {
return p.Status.PodIP
}
var podIP string
if p.Status.PodIPs != nil {
for _, ip := range p.Status.PodIPs {
if ipMatchesConfig(ip.IP) {
podIP = ip.IP
}
}
}
return podIP
}
func getPodNodeName(p v1.Pod) string {
if GoldpingerConfig.DisplayNodeName {
return p.Spec.NodeName
}
return p.Name
}
// GetAllPods returns a mapping from a pod name to a pointer to a GoldpingerPod(s)
func GetAllPods() map[string]*GoldpingerPod {
timer := GetLabeledKubernetesCallsTimer()
pods, err := GoldpingerConfig.KubernetesClient.CoreV1().Pods(namespace).List(metav1.ListOptions{LabelSelector: GoldpingerConfig.LabelSelector})
listOpts := metav1.ListOptions{
LabelSelector: GoldpingerConfig.LabelSelector,
FieldSelector: "status.phase=Running", // only select Running pods, otherwise we will get them before they have IPs
}
pods, err := GoldpingerConfig.KubernetesClient.CoreV1().Pods(*GoldpingerConfig.Namespace).List(context.TODO(), listOpts)
if err != nil {
zap.L().Error("Error getting pods for selector", zap.String("selector", GoldpingerConfig.LabelSelector), zap.Error(err))
CountError("kubernetes_api")
@@ -52,13 +118,33 @@ func GetAllPods() map[string]*GoldpingerPod {
timer.ObserveDuration()
}
var podMap = make(map[string]*GoldpingerPod)
podMap := make(map[string]*GoldpingerPod)
for _, pod := range pods.Items {
podMap[pod.Name] = &GoldpingerPod{
Name: pod.Name,
PodIP: pod.Status.PodIP,
HostIP: pod.Status.HostIP,
Name: getPodNodeName(pod),
PodIP: getPodIP(pod),
HostIP: getHostIP(pod),
}
}
return podMap
}
// ipMatchesConfig checks if the input IP family matches the first entry in the IPVersions config.
// TODO update to check all config versions to support dual-stack pinging.
func ipMatchesConfig(ip string) bool {
ipFamily := getIPFamily(ip)
return GoldpingerConfig.IPVersions[0] == string(ipFamily)
}
// getIPFamily returns the IP family of the input IP.
// Possible values are 4 and 6.
func getIPFamily(ip string) k8snet.IPFamily {
if k8snet.IsIPv4String(ip) {
return k8snet.IPv4
}
if k8snet.IsIPv6String(ip) {
return k8snet.IPv6
}
zap.L().Error("Error determining IP family", zap.String("IP", ip))
return ""
}

View File

@@ -46,7 +46,7 @@ type Pinger struct {
func NewPinger(pod *GoldpingerPod, resultsChan chan<- PingAllPodsResult) *Pinger {
p := Pinger{
pod: pod,
timeout: time.Duration(GoldpingerConfig.PingTimeoutMs) * time.Millisecond,
timeout: GoldpingerConfig.PingTimeout,
resultsChan: resultsChan,
stopChan: make(chan struct{}),

72
pkg/goldpinger/probes.go Normal file
View File

@@ -0,0 +1,72 @@
// 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 (
"context"
"crypto/tls"
"fmt"
"net"
"net/http"
"net/url"
"time"
)
func doDNSProbe(addr string, timeout time.Duration) error {
resolver := net.Resolver{}
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
ips, err := resolver.LookupHost(ctx, addr)
if len(ips) == 0 {
return fmt.Errorf("%s was resolved to 0 ips", addr)
}
return err
}
func doTCPProbe(addr string, timeout time.Duration) error {
conn, err := net.DialTimeout("tcp", addr, timeout)
if conn != nil {
defer conn.Close()
}
return err
}
func doHTTPProbe(addr string, timeout time.Duration) error {
client := http.Client{Timeout: timeout}
u, err := url.Parse(addr)
if err != nil {
return err
}
if u.Scheme != "http" && u.Scheme != "https" {
return fmt.Errorf("invalid url scheme: '%s' in address", u.Scheme)
}
if u.Scheme == "https" {
client.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
}
resp, err := client.Get(addr)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return fmt.Errorf("%s returned non-200 resp: %d", addr, resp.StatusCode)
}
return err
}

View File

@@ -48,6 +48,16 @@ var (
},
)
goldpingerClusterHealthGauge = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "goldpinger_cluster_health_total",
Help: "1 if all check pass, 0 otherwise",
},
[]string{
"goldpinger_instance",
},
)
goldpingerResponseTimePeersHistogram = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "goldpinger_peers_response_time_s",
@@ -93,17 +103,39 @@ var (
"host",
},
)
goldPingerTcpErrorsCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "goldpinger_tcp_errors_total",
Help: "Statistics of TCP probe errors per instance",
},
[]string{
"goldpinger_instance",
"host",
},
)
goldPingerHttpErrorsCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "goldpinger_http_errors_total",
Help: "Statistics of HTTP probe errors per instance",
},
[]string{
"goldpinger_instance",
"host",
},
)
bootTime = time.Now()
)
func init() {
prometheus.MustRegister(goldpingerStatsCounter)
prometheus.MustRegister(goldpingerNodesHealthGauge)
prometheus.MustRegister(goldpingerClusterHealthGauge)
prometheus.MustRegister(goldpingerResponseTimePeersHistogram)
prometheus.MustRegister(goldpingerResponseTimeKubernetesHistogram)
prometheus.MustRegister(goldpingerErrorsCounter)
prometheus.MustRegister(goldpingerDnsErrorsCounter)
prometheus.MustRegister(goldPingerHttpErrorsCounter)
prometheus.MustRegister(goldPingerTcpErrorsCounter)
zap.L().Info("Metrics setup - see /metrics")
}
@@ -135,6 +167,17 @@ func CountHealthyUnhealthyNodes(healthy, unhealthy float64) {
).Set(unhealthy)
}
// SetClusterHealth sets the cluster health gauge to 1 (healthy) or 0 (unhealthy)
func SetClusterHealth(healthy bool) {
value := 1.0
if !healthy {
value = 0
}
goldpingerClusterHealthGauge.WithLabelValues(
GoldpingerConfig.Hostname,
).Set(value)
}
// counts instances of various errors
func CountError(errorType string) {
goldpingerErrorsCounter.WithLabelValues(
@@ -151,6 +194,22 @@ func CountDnsError(host string) {
).Inc()
}
// CountTcpError counts instances of tcp errors for prober
func CountTcpError(host string) {
goldPingerTcpErrorsCounter.WithLabelValues(
GoldpingerConfig.Hostname,
host,
).Inc()
}
// CountHttpError counts instances of tcp errors for prober
func CountHttpError(host string) {
goldPingerHttpErrorsCounter.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

@@ -34,8 +34,8 @@ var checkResultsMux = sync.Mutex{}
// - there is already a pinger with the same name
// - the pinger has the same podIP
// - the pinger has the same hostIP
func exists(existingPods map[string]*GoldpingerPod, new *GoldpingerPod) bool {
old, exists := existingPods[new.Name]
func exists(existingPods map[string]*GoldpingerPod, podName string, new *GoldpingerPod) bool {
old, exists := existingPods[podName]
return exists && (old.PodIP == new.PodIP) && (old.HostIP == new.HostIP)
}
@@ -61,7 +61,7 @@ func updatePingers(resultsChan chan<- PingAllPodsResult) {
latest := SelectPods()
for podName, pod := range latest {
if exists(existingPods, pod) {
if exists(existingPods, podName, pod) {
// This pod continues to exist in the latest iteration of the update
// without any changes
// Delete it from the set of pods that we wish to delete
@@ -153,6 +153,22 @@ func updateCounters() {
}
}
CountHealthyUnhealthyNodes(counterHealthy, float64(len(checkResults.PodResults))-counterHealthy)
// check external targets, don't block the access to checkResultsMux
nodesHealthy := int(counterHealthy) == len(checkResults.PodResults)
go func(healthySoFar bool) {
if healthySoFar {
probeResults := checkTargets()
for host := range probeResults {
for _, response := range probeResults[host] {
if response.Error != "" {
healthySoFar = false
break
}
}
}
}
SetClusterHealth(healthySoFar)
}(nodesHealthy)
}
// collectResults simply reads results from the results channel and saves them in a map

View File

@@ -6,6 +6,8 @@ package models
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
@@ -30,6 +32,11 @@ func (m *CallStats) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this call stats based on context it is used
func (m *CallStats) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *CallStats) MarshalBinary() ([]byte, error) {
if m == nil {

View File

@@ -6,6 +6,8 @@ package models
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
@@ -61,7 +63,6 @@ func (m *CheckAllPodResult) Validate(formats strfmt.Registry) error {
}
func (m *CheckAllPodResult) validateHostIP(formats strfmt.Registry) error {
if swag.IsZero(m.HostIP) { // not required
return nil
}
@@ -74,7 +75,6 @@ func (m *CheckAllPodResult) validateHostIP(formats strfmt.Registry) error {
}
func (m *CheckAllPodResult) validatePodIP(formats strfmt.Registry) error {
if swag.IsZero(m.PodIP) { // not required
return nil
}
@@ -87,7 +87,6 @@ func (m *CheckAllPodResult) validatePodIP(formats strfmt.Registry) error {
}
func (m *CheckAllPodResult) validateResponse(formats strfmt.Registry) error {
if swag.IsZero(m.Response) { // not required
return nil
}
@@ -96,6 +95,38 @@ func (m *CheckAllPodResult) validateResponse(formats strfmt.Registry) error {
if err := m.Response.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("response")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("response")
}
return err
}
}
return nil
}
// ContextValidate validate this check all pod result based on the context it is used
func (m *CheckAllPodResult) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateResponse(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *CheckAllPodResult) contextValidateResponse(ctx context.Context, formats strfmt.Registry) error {
if m.Response != nil {
if err := m.Response.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("response")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("response")
}
return err
}

View File

@@ -6,6 +6,7 @@ package models
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"strconv"
"github.com/go-openapi/errors"
@@ -22,9 +23,6 @@ type CheckAllResults struct {
// o k
OK *bool `json:"OK,omitempty"`
// dns results
DNSResults map[string]DNSResults `json:"dnsResults,omitempty"`
// hosts
Hosts []*CheckAllResultsHostsItems0 `json:"hosts"`
@@ -34,6 +32,9 @@ type CheckAllResults struct {
// hosts number
HostsNumber int32 `json:"hosts-number,omitempty"`
// probe results
ProbeResults map[string]ProbeResults `json:"probeResults,omitempty"`
// responses
Responses map[string]CheckAllPodResult `json:"responses,omitempty"`
}
@@ -42,11 +43,11 @@ type CheckAllResults struct {
func (m *CheckAllResults) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateDNSResults(formats); err != nil {
if err := m.validateHosts(formats); err != nil {
res = append(res, err)
}
if err := m.validateHosts(formats); err != nil {
if err := m.validateProbeResults(formats); err != nil {
res = append(res, err)
}
@@ -60,27 +61,7 @@ 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
return nil
}
@@ -94,6 +75,8 @@ func (m *CheckAllResults) validateHosts(formats strfmt.Registry) error {
if err := m.Hosts[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("hosts" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("hosts" + "." + strconv.Itoa(i))
}
return err
}
@@ -104,8 +87,25 @@ func (m *CheckAllResults) validateHosts(formats strfmt.Registry) error {
return nil
}
func (m *CheckAllResults) validateResponses(formats strfmt.Registry) error {
func (m *CheckAllResults) validateProbeResults(formats strfmt.Registry) error {
if swag.IsZero(m.ProbeResults) { // not required
return nil
}
for k := range m.ProbeResults {
if val, ok := m.ProbeResults[k]; ok {
if err := val.Validate(formats); err != nil {
return err
}
}
}
return nil
}
func (m *CheckAllResults) validateResponses(formats strfmt.Registry) error {
if swag.IsZero(m.Responses) { // not required
return nil
}
@@ -117,6 +117,83 @@ func (m *CheckAllResults) validateResponses(formats strfmt.Registry) error {
}
if val, ok := m.Responses[k]; ok {
if err := val.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("responses" + "." + k)
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("responses" + "." + k)
}
return err
}
}
}
return nil
}
// ContextValidate validate this check all results based on the context it is used
func (m *CheckAllResults) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateHosts(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateProbeResults(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateResponses(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *CheckAllResults) contextValidateHosts(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Hosts); i++ {
if m.Hosts[i] != nil {
if err := m.Hosts[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("hosts" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("hosts" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *CheckAllResults) contextValidateProbeResults(ctx context.Context, formats strfmt.Registry) error {
for k := range m.ProbeResults {
if val, ok := m.ProbeResults[k]; ok {
if err := val.ContextValidate(ctx, formats); err != nil {
return err
}
}
}
return nil
}
func (m *CheckAllResults) contextValidateResponses(ctx context.Context, formats strfmt.Registry) error {
for k := range m.Responses {
if val, ok := m.Responses[k]; ok {
if err := val.ContextValidate(ctx, formats); err != nil {
return err
}
}
@@ -180,7 +257,6 @@ func (m *CheckAllResultsHostsItems0) Validate(formats strfmt.Registry) error {
}
func (m *CheckAllResultsHostsItems0) validateHostIP(formats strfmt.Registry) error {
if swag.IsZero(m.HostIP) { // not required
return nil
}
@@ -193,7 +269,6 @@ func (m *CheckAllResultsHostsItems0) validateHostIP(formats strfmt.Registry) err
}
func (m *CheckAllResultsHostsItems0) validatePodIP(formats strfmt.Registry) error {
if swag.IsZero(m.PodIP) { // not required
return nil
}
@@ -205,6 +280,11 @@ func (m *CheckAllResultsHostsItems0) validatePodIP(formats strfmt.Registry) erro
return nil
}
// ContextValidate validates this check all results hosts items0 based on context it is used
func (m *CheckAllResultsHostsItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *CheckAllResultsHostsItems0) MarshalBinary() ([]byte, error) {
if m == nil {

View File

@@ -6,6 +6,8 @@ package models
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
@@ -17,22 +19,22 @@ import (
// swagger:model CheckResults
type CheckResults struct {
// dns results
DNSResults DNSResults `json:"dnsResults,omitempty"`
// pod results
PodResults map[string]PodResult `json:"podResults,omitempty"`
// probe results
ProbeResults ProbeResults `json:"probeResults,omitempty"`
}
// Validate validates this check results
func (m *CheckResults) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateDNSResults(formats); err != nil {
if err := m.validatePodResults(formats); err != nil {
res = append(res, err)
}
if err := m.validatePodResults(formats); err != nil {
if err := m.validateProbeResults(formats); err != nil {
res = append(res, err)
}
@@ -42,24 +44,7 @@ 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
}
@@ -71,6 +56,11 @@ func (m *CheckResults) validatePodResults(formats strfmt.Registry) error {
}
if val, ok := m.PodResults[k]; ok {
if err := val.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("podResults" + "." + k)
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("podResults" + "." + k)
}
return err
}
}
@@ -80,6 +70,72 @@ func (m *CheckResults) validatePodResults(formats strfmt.Registry) error {
return nil
}
func (m *CheckResults) validateProbeResults(formats strfmt.Registry) error {
if swag.IsZero(m.ProbeResults) { // not required
return nil
}
if m.ProbeResults != nil {
if err := m.ProbeResults.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("probeResults")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("probeResults")
}
return err
}
}
return nil
}
// ContextValidate validate this check results based on the context it is used
func (m *CheckResults) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidatePodResults(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateProbeResults(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *CheckResults) contextValidatePodResults(ctx context.Context, formats strfmt.Registry) error {
for k := range m.PodResults {
if val, ok := m.PodResults[k]; ok {
if err := val.ContextValidate(ctx, formats); err != nil {
return err
}
}
}
return nil
}
func (m *CheckResults) contextValidateProbeResults(ctx context.Context, formats strfmt.Registry) error {
if err := m.ProbeResults.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("probeResults")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("probeResults")
}
return err
}
return nil
}
// MarshalBinary interface implementation
func (m *CheckResults) MarshalBinary() ([]byte, error) {
if m == nil {

View File

@@ -0,0 +1,103 @@
// 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 (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// ClusterHealthResults cluster health results
//
// swagger:model ClusterHealthResults
type ClusterHealthResults struct {
// o k
// Required: true
OK bool `json:"OK"`
// duration ns
DurationNs int64 `json:"duration-ns,omitempty"`
// generated at
// Format: date-time
GeneratedAt strfmt.DateTime `json:"generated-at,omitempty"`
// nodes healthy
NodesHealthy []string `json:"nodesHealthy"`
// nodes total
NodesTotal int64 `json:"nodesTotal,omitempty"`
// nodes unhealthy
NodesUnhealthy []string `json:"nodesUnhealthy"`
}
// Validate validates this cluster health results
func (m *ClusterHealthResults) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateOK(formats); err != nil {
res = append(res, err)
}
if err := m.validateGeneratedAt(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *ClusterHealthResults) validateOK(formats strfmt.Registry) error {
if err := validate.Required("OK", "body", bool(m.OK)); err != nil {
return err
}
return nil
}
func (m *ClusterHealthResults) validateGeneratedAt(formats strfmt.Registry) error {
if swag.IsZero(m.GeneratedAt) { // not required
return nil
}
if err := validate.FormatOf("generated-at", "body", "date-time", m.GeneratedAt.String(), formats); err != nil {
return err
}
return nil
}
// ContextValidate validates this cluster health results based on context it is used
func (m *ClusterHealthResults) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *ClusterHealthResults) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *ClusterHealthResults) UnmarshalBinary(b []byte) error {
var res ClusterHealthResults
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -6,6 +6,8 @@ package models
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
@@ -27,6 +29,11 @@ func (m *DNSResult) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this Dns result based on context it is used
func (m *DNSResult) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *DNSResult) MarshalBinary() ([]byte, error) {
if m == nil {

View File

@@ -6,6 +6,8 @@ package models
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/validate"
@@ -38,3 +40,23 @@ func (m DNSResults) Validate(formats strfmt.Registry) error {
}
return nil
}
// ContextValidate validate this Dns results based on the context it is used
func (m DNSResults) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
for k := range m {
if val, ok := m[k]; ok {
if err := val.ContextValidate(ctx, formats); err != nil {
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -6,6 +6,8 @@ package models
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
@@ -43,7 +45,6 @@ func (m *HealthCheckResults) Validate(formats strfmt.Registry) error {
}
func (m *HealthCheckResults) validateGeneratedAt(formats strfmt.Registry) error {
if swag.IsZero(m.GeneratedAt) { // not required
return nil
}
@@ -55,6 +56,11 @@ func (m *HealthCheckResults) validateGeneratedAt(formats strfmt.Registry) error
return nil
}
// ContextValidate validates this health check results based on context it is used
func (m *HealthCheckResults) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *HealthCheckResults) MarshalBinary() ([]byte, error) {
if m == nil {

View File

@@ -6,6 +6,8 @@ package models
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
@@ -44,7 +46,6 @@ func (m *PingResults) Validate(formats strfmt.Registry) error {
}
func (m *PingResults) validateBootTime(formats strfmt.Registry) error {
if swag.IsZero(m.BootTime) { // not required
return nil
}
@@ -57,7 +58,6 @@ func (m *PingResults) validateBootTime(formats strfmt.Registry) error {
}
func (m *PingResults) validateReceived(formats strfmt.Registry) error {
if swag.IsZero(m.Received) { // not required
return nil
}
@@ -66,6 +66,38 @@ func (m *PingResults) validateReceived(formats strfmt.Registry) error {
if err := m.Received.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("received")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("received")
}
return err
}
}
return nil
}
// ContextValidate validate this ping results based on the context it is used
func (m *PingResults) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateReceived(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *PingResults) contextValidateReceived(ctx context.Context, formats strfmt.Registry) error {
if m.Received != nil {
if err := m.Received.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("received")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("received")
}
return err
}

View File

@@ -6,6 +6,8 @@ package models
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
@@ -72,7 +74,6 @@ func (m *PodResult) Validate(formats strfmt.Registry) error {
}
func (m *PodResult) validateHostIP(formats strfmt.Registry) error {
if swag.IsZero(m.HostIP) { // not required
return nil
}
@@ -85,7 +86,6 @@ func (m *PodResult) validateHostIP(formats strfmt.Registry) error {
}
func (m *PodResult) validatePingTime(formats strfmt.Registry) error {
if swag.IsZero(m.PingTime) { // not required
return nil
}
@@ -98,7 +98,6 @@ func (m *PodResult) validatePingTime(formats strfmt.Registry) error {
}
func (m *PodResult) validatePodIP(formats strfmt.Registry) error {
if swag.IsZero(m.PodIP) { // not required
return nil
}
@@ -111,7 +110,6 @@ func (m *PodResult) validatePodIP(formats strfmt.Registry) error {
}
func (m *PodResult) validateResponse(formats strfmt.Registry) error {
if swag.IsZero(m.Response) { // not required
return nil
}
@@ -120,6 +118,38 @@ func (m *PodResult) validateResponse(formats strfmt.Registry) error {
if err := m.Response.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("response")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("response")
}
return err
}
}
return nil
}
// ContextValidate validate this pod result based on the context it is used
func (m *PodResult) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateResponse(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *PodResult) contextValidateResponse(ctx context.Context, formats strfmt.Registry) error {
if m.Response != nil {
if err := m.Response.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("response")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("response")
}
return err
}

View File

@@ -0,0 +1,56 @@
// 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 (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// ProbeResult probe result
//
// swagger:model ProbeResult
type ProbeResult struct {
// error
Error string `json:"error,omitempty"`
// protocol
Protocol string `json:"protocol,omitempty"`
// response time ms
ResponseTimeMs int64 `json:"response-time-ms,omitempty"`
}
// Validate validates this probe result
func (m *ProbeResult) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this probe result based on context it is used
func (m *ProbeResult) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *ProbeResult) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *ProbeResult) UnmarshalBinary(b []byte) error {
var res ProbeResult
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,78 @@
// 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 (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/validate"
)
// ProbeResults probe results
//
// swagger:model ProbeResults
type ProbeResults map[string][]ProbeResult
// Validate validates this probe results
func (m ProbeResults) Validate(formats strfmt.Registry) error {
var res []error
for k := range m {
if err := validate.Required(k, "body", m[k]); err != nil {
return err
}
for i := 0; i < len(m[k]); i++ {
if err := m[k][i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(k + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName(k + "." + strconv.Itoa(i))
}
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// ContextValidate validate this probe results based on the context it is used
func (m ProbeResults) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
for k := range m {
for i := 0; i < len(m[k]); i++ {
if err := m[k][i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(k + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName(k + "." + strconv.Itoa(i))
}
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -20,7 +20,6 @@ import (
"context"
"crypto/tls"
"net/http"
"time"
"strings"
@@ -61,7 +60,7 @@ func configureAPI(api *operations.GoldpingerAPI) http.Handler {
ctx, cancel := context.WithTimeout(
params.HTTPRequest.Context(),
time.Duration(goldpinger.GoldpingerConfig.PingTimeoutMs)*time.Millisecond,
goldpinger.GoldpingerConfig.PingTimeout,
)
defer cancel()
@@ -74,7 +73,7 @@ func configureAPI(api *operations.GoldpingerAPI) http.Handler {
ctx, cancel := context.WithTimeout(
params.HTTPRequest.Context(),
time.Duration(goldpinger.GoldpingerConfig.CheckTimeoutMs)*time.Millisecond,
goldpinger.GoldpingerConfig.CheckTimeout,
)
defer cancel()
@@ -87,13 +86,31 @@ func configureAPI(api *operations.GoldpingerAPI) http.Handler {
ctx, cancel := context.WithTimeout(
params.HTTPRequest.Context(),
time.Duration(goldpinger.GoldpingerConfig.CheckAllTimeoutMs)*time.Millisecond,
goldpinger.GoldpingerConfig.CheckAllTimeout,
)
defer cancel()
return operations.NewCheckAllPodsOK().WithPayload(goldpinger.CheckNeighboursNeighbours(ctx))
})
api.ClusterHealthHandler = operations.ClusterHealthHandlerFunc(
func(params operations.ClusterHealthParams) middleware.Responder {
goldpinger.CountCall("received", "cluster_health")
ctx, cancel := context.WithTimeout(
params.HTTPRequest.Context(),
goldpinger.GoldpingerConfig.CheckAllTimeout,
)
defer cancel()
payload := goldpinger.CheckCluster(ctx)
if payload.OK {
return operations.NewClusterHealthOK().WithPayload(payload)
} else {
return operations.NewClusterHealthIMATeapot().WithPayload(payload)
}
})
api.HealthzHandler = operations.HealthzHandlerFunc(
func(params operations.HealthzParams) middleware.Responder {
goldpinger.CountCall("received", "healthz")

View File

@@ -58,6 +58,29 @@ func init() {
}
}
},
"/cluster_health": {
"get": {
"description": "Checks the full graph. Returns a binary OK or not OK.",
"produces": [
"application/json"
],
"operationId": "clusterHealth",
"responses": {
"200": {
"description": "Healthy cluster",
"schema": {
"$ref": "#/definitions/ClusterHealthResults"
}
},
"418": {
"description": "Unhealthy cluster",
"schema": {
"$ref": "#/definitions/ClusterHealthResults"
}
}
}
}
},
"/healthz": {
"get": {
"description": "The healthcheck endpoint provides detailed information about the health of a web service. If each of the components required by the service are healthy, then the service is considered healthy and will return a 200 OK response. If any of the components needed by the service are unhealthy, then a 503 Service Unavailable response will be provided.",
@@ -180,11 +203,23 @@ func init() {
"type": "integer",
"format": "int32"
},
"httpResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/HttpResults"
}
},
"responses": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/CheckAllPodResult"
}
},
"tcpResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/TcpResults"
}
}
}
},
@@ -194,29 +229,60 @@ func init() {
"dnsResults": {
"$ref": "#/definitions/DnsResults"
},
"httpResults": {
"$ref": "#/definitions/HttpResults"
},
"podResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/PodResult"
}
},
"tcpResults": {
"$ref": "#/definitions/TcpResults"
}
}
},
"DnsResult": {
"ClusterHealthResults": {
"type": "object",
"required": [
"OK"
],
"properties": {
"error": {
"type": "string"
"OK": {
"type": "boolean",
"default": false
},
"response-time-ms": {
"type": "number",
"duration-ns": {
"type": "integer",
"format": "int64"
},
"generated-at": {
"type": "string",
"format": "date-time"
},
"nodesHealthy": {
"type": "array",
"items": {
"type": "string"
}
},
"nodesTotal": {
"type": "integer",
"format": "int64"
},
"nodesUnhealthy": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"DnsResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/DnsResult"
"$ref": "#/definitions/ProbeResult"
}
},
"HealthCheckResults": {
@@ -236,6 +302,12 @@ func init() {
}
}
},
"HttpResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/ProbeResult"
}
},
"PingResults": {
"type": "object",
"properties": {
@@ -283,6 +355,23 @@ func init() {
"format": "int32"
}
}
},
"ProbeResult": {
"properties": {
"error": {
"type": "string"
},
"response-time-ms": {
"type": "number",
"format": "int64"
}
}
},
"TcpResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/ProbeResult"
}
}
}
}`))
@@ -327,6 +416,29 @@ func init() {
}
}
},
"/cluster_health": {
"get": {
"description": "Checks the full graph. Returns a binary OK or not OK.",
"produces": [
"application/json"
],
"operationId": "clusterHealth",
"responses": {
"200": {
"description": "Healthy cluster",
"schema": {
"$ref": "#/definitions/ClusterHealthResults"
}
},
"418": {
"description": "Unhealthy cluster",
"schema": {
"$ref": "#/definitions/ClusterHealthResults"
}
}
}
}
},
"/healthz": {
"get": {
"description": "The healthcheck endpoint provides detailed information about the health of a web service. If each of the components required by the service are healthy, then the service is considered healthy and will return a 200 OK response. If any of the components needed by the service are unhealthy, then a 503 Service Unavailable response will be provided.",
@@ -436,11 +548,23 @@ func init() {
"type": "integer",
"format": "int32"
},
"httpResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/HttpResults"
}
},
"responses": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/CheckAllPodResult"
}
},
"tcpResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/TcpResults"
}
}
}
},
@@ -466,29 +590,60 @@ func init() {
"dnsResults": {
"$ref": "#/definitions/DnsResults"
},
"httpResults": {
"$ref": "#/definitions/HttpResults"
},
"podResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/PodResult"
}
},
"tcpResults": {
"$ref": "#/definitions/TcpResults"
}
}
},
"DnsResult": {
"ClusterHealthResults": {
"type": "object",
"required": [
"OK"
],
"properties": {
"error": {
"type": "string"
"OK": {
"type": "boolean",
"default": false
},
"response-time-ms": {
"type": "number",
"duration-ns": {
"type": "integer",
"format": "int64"
},
"generated-at": {
"type": "string",
"format": "date-time"
},
"nodesHealthy": {
"type": "array",
"items": {
"type": "string"
}
},
"nodesTotal": {
"type": "integer",
"format": "int64"
},
"nodesUnhealthy": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"DnsResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/DnsResult"
"$ref": "#/definitions/ProbeResult"
}
},
"HealthCheckResults": {
@@ -508,6 +663,12 @@ func init() {
}
}
},
"HttpResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/ProbeResult"
}
},
"PingResults": {
"type": "object",
"properties": {
@@ -555,6 +716,23 @@ func init() {
"format": "int32"
}
}
},
"ProbeResult": {
"properties": {
"error": {
"type": "string"
},
"response-time-ms": {
"type": "number",
"format": "int64"
}
}
},
"TcpResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/ProbeResult"
}
}
}
}`))

View File

@@ -29,7 +29,7 @@ func NewCheckAllPods(ctx *middleware.Context, handler CheckAllPodsHandler) *Chec
return &CheckAllPods{Context: ctx, Handler: handler}
}
/*CheckAllPods swagger:route GET /check_all checkAllPods
/* CheckAllPods swagger:route GET /check_all checkAllPods
Queries the API server for all other pods in this service, and makes all of them query all of their neighbours, using their pods IPs. Calls their /check endpoint.
@@ -42,17 +42,15 @@ type CheckAllPods struct {
func (o *CheckAllPods) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
r = rCtx
*r = *rCtx
}
var Params = NewCheckAllPodsParams()
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -13,7 +13,8 @@ import (
)
// NewCheckAllPodsParams creates a new CheckAllPodsParams object
// no default values defined in spec.
//
// There are no default values defined in the spec.
func NewCheckAllPodsParams() CheckAllPodsParams {
return CheckAllPodsParams{}

View File

@@ -29,7 +29,7 @@ func NewCheckServicePods(ctx *middleware.Context, handler CheckServicePodsHandle
return &CheckServicePods{Context: ctx, Handler: handler}
}
/*CheckServicePods swagger:route GET /check checkServicePods
/* CheckServicePods swagger:route GET /check checkServicePods
Queries the API server for all other pods in this service, and pings them via their pods IPs. Calls their /ping endpoint
@@ -42,17 +42,15 @@ type CheckServicePods struct {
func (o *CheckServicePods) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
r = rCtx
*r = *rCtx
}
var Params = NewCheckServicePodsParams()
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -13,7 +13,8 @@ import (
)
// NewCheckServicePodsParams creates a new CheckServicePodsParams object
// no default values defined in spec.
//
// There are no default values defined in the spec.
func NewCheckServicePodsParams() CheckServicePodsParams {
return CheckServicePodsParams{}

View File

@@ -0,0 +1,56 @@
// Code generated by go-swagger; DO NOT EDIT.
package operations
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
)
// ClusterHealthHandlerFunc turns a function with the right signature into a cluster health handler
type ClusterHealthHandlerFunc func(ClusterHealthParams) middleware.Responder
// Handle executing the request and returning a response
func (fn ClusterHealthHandlerFunc) Handle(params ClusterHealthParams) middleware.Responder {
return fn(params)
}
// ClusterHealthHandler interface for that can handle valid cluster health params
type ClusterHealthHandler interface {
Handle(ClusterHealthParams) middleware.Responder
}
// NewClusterHealth creates a new http.Handler for the cluster health operation
func NewClusterHealth(ctx *middleware.Context, handler ClusterHealthHandler) *ClusterHealth {
return &ClusterHealth{Context: ctx, Handler: handler}
}
/* ClusterHealth swagger:route GET /cluster_health clusterHealth
Checks the full graph. Returns a binary OK or not OK.
*/
type ClusterHealth struct {
Context *middleware.Context
Handler ClusterHealthHandler
}
func (o *ClusterHealth) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewClusterHealthParams()
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -0,0 +1,46 @@
// Code generated by go-swagger; DO NOT EDIT.
package operations
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime/middleware"
)
// NewClusterHealthParams creates a new ClusterHealthParams object
//
// There are no default values defined in the spec.
func NewClusterHealthParams() ClusterHealthParams {
return ClusterHealthParams{}
}
// ClusterHealthParams contains all the bound params for the cluster health operation
// typically these are obtained from a http.Request
//
// swagger:parameters clusterHealth
type ClusterHealthParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewClusterHealthParams() beforehand.
func (o *ClusterHealthParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -0,0 +1,102 @@
// Code generated by go-swagger; DO NOT EDIT.
package operations
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/bloomberg/goldpinger/v3/pkg/models"
)
// ClusterHealthOKCode is the HTTP code returned for type ClusterHealthOK
const ClusterHealthOKCode int = 200
/*ClusterHealthOK Healthy cluster
swagger:response clusterHealthOK
*/
type ClusterHealthOK struct {
/*
In: Body
*/
Payload *models.ClusterHealthResults `json:"body,omitempty"`
}
// NewClusterHealthOK creates ClusterHealthOK with default headers values
func NewClusterHealthOK() *ClusterHealthOK {
return &ClusterHealthOK{}
}
// WithPayload adds the payload to the cluster health o k response
func (o *ClusterHealthOK) WithPayload(payload *models.ClusterHealthResults) *ClusterHealthOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the cluster health o k response
func (o *ClusterHealthOK) SetPayload(payload *models.ClusterHealthResults) {
o.Payload = payload
}
// WriteResponse to the client
func (o *ClusterHealthOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
// ClusterHealthIMATeapotCode is the HTTP code returned for type ClusterHealthIMATeapot
const ClusterHealthIMATeapotCode int = 418
/*ClusterHealthIMATeapot Unhealthy cluster
swagger:response clusterHealthIMATeapot
*/
type ClusterHealthIMATeapot struct {
/*
In: Body
*/
Payload *models.ClusterHealthResults `json:"body,omitempty"`
}
// NewClusterHealthIMATeapot creates ClusterHealthIMATeapot with default headers values
func NewClusterHealthIMATeapot() *ClusterHealthIMATeapot {
return &ClusterHealthIMATeapot{}
}
// WithPayload adds the payload to the cluster health i m a teapot response
func (o *ClusterHealthIMATeapot) WithPayload(payload *models.ClusterHealthResults) *ClusterHealthIMATeapot {
o.Payload = payload
return o
}
// SetPayload sets the payload to the cluster health i m a teapot response
func (o *ClusterHealthIMATeapot) SetPayload(payload *models.ClusterHealthResults) {
o.Payload = payload
}
// WriteResponse to the client
func (o *ClusterHealthIMATeapot) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(418)
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

@@ -0,0 +1,84 @@
// Code generated by go-swagger; DO NOT EDIT.
package operations
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
)
// ClusterHealthURL generates an URL for the cluster health operation
type ClusterHealthURL struct {
_basePath string
}
// WithBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *ClusterHealthURL) WithBasePath(bp string) *ClusterHealthURL {
o.SetBasePath(bp)
return o
}
// SetBasePath sets the base path for this url builder, only required when it's different from the
// base path specified in the swagger spec.
// When the value of the base path is an empty string
func (o *ClusterHealthURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *ClusterHealthURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/cluster_health"
_basePath := o._basePath
_result.Path = golangswaggerpaths.Join(_basePath, _path)
return &_result, nil
}
// Must is a helper function to panic when the url builder returns an error
func (o *ClusterHealthURL) Must(u *url.URL, err error) *url.URL {
if err != nil {
panic(err)
}
if u == nil {
panic("url can't be nil")
}
return u
}
// String returns the string representation of the path with query string
func (o *ClusterHealthURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *ClusterHealthURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on ClusterHealthURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on ClusterHealthURL")
}
base, err := o.Build()
if err != nil {
return nil, err
}
base.Scheme = scheme
base.Host = host
return base, nil
}
// StringFull returns the string representation of a complete url
func (o *ClusterHealthURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -32,6 +32,7 @@ func NewGoldpingerAPI(spec *loads.Document) *GoldpingerAPI {
PreServerShutdown: func() {},
ServerShutdown: func() {},
spec: spec,
useSwaggerUI: false,
ServeError: errors.ServeError,
BasicAuthenticator: security.BasicAuth,
APIKeyAuthenticator: security.APIKeyAuth,
@@ -47,6 +48,9 @@ func NewGoldpingerAPI(spec *loads.Document) *GoldpingerAPI {
CheckServicePodsHandler: CheckServicePodsHandlerFunc(func(params CheckServicePodsParams) middleware.Responder {
return middleware.NotImplemented("operation CheckServicePods has not yet been implemented")
}),
ClusterHealthHandler: ClusterHealthHandlerFunc(func(params ClusterHealthParams) middleware.Responder {
return middleware.NotImplemented("operation ClusterHealth has not yet been implemented")
}),
HealthzHandler: HealthzHandlerFunc(func(params HealthzParams) middleware.Responder {
return middleware.NotImplemented("operation Healthz has not yet been implemented")
}),
@@ -67,13 +71,16 @@ type GoldpingerAPI struct {
defaultConsumes string
defaultProduces string
Middleware func(middleware.Builder) http.Handler
useSwaggerUI bool
// BasicAuthenticator generates a runtime.Authenticator from the supplied basic auth function.
// 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 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 implementation in the security package, however you can replace it for your particular usage.
BearerAuthenticator func(string, security.ScopedTokenAuthentication) runtime.Authenticator
@@ -90,10 +97,13 @@ type GoldpingerAPI struct {
CheckAllPodsHandler CheckAllPodsHandler
// CheckServicePodsHandler sets the operation handler for the check service pods operation
CheckServicePodsHandler CheckServicePodsHandler
// ClusterHealthHandler sets the operation handler for the cluster health operation
ClusterHealthHandler ClusterHealthHandler
// HealthzHandler sets the operation handler for the healthz operation
HealthzHandler HealthzHandler
// PingHandler sets the operation handler for the ping operation
PingHandler PingHandler
// ServeError is called when an error is received, there is a default handler
// but you can set your own with this
ServeError func(http.ResponseWriter, *http.Request, error)
@@ -113,6 +123,16 @@ type GoldpingerAPI struct {
Logger func(string, ...interface{})
}
// UseRedoc for documentation at /docs
func (o *GoldpingerAPI) UseRedoc() {
o.useSwaggerUI = false
}
// UseSwaggerUI for documentation at /docs
func (o *GoldpingerAPI) UseSwaggerUI() {
o.useSwaggerUI = true
}
// SetDefaultProduces sets the default produces media type
func (o *GoldpingerAPI) SetDefaultProduces(mediaType string) {
o.defaultProduces = mediaType
@@ -166,6 +186,9 @@ func (o *GoldpingerAPI) Validate() error {
if o.CheckServicePodsHandler == nil {
unregistered = append(unregistered, "CheckServicePodsHandler")
}
if o.ClusterHealthHandler == nil {
unregistered = append(unregistered, "ClusterHealthHandler")
}
if o.HealthzHandler == nil {
unregistered = append(unregistered, "HealthzHandler")
}
@@ -271,6 +294,10 @@ func (o *GoldpingerAPI) initHandlerCache() {
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/cluster_health"] = NewClusterHealth(o.context, o.ClusterHealthHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/healthz"] = NewHealthz(o.context, o.HealthzHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
@@ -286,6 +313,9 @@ func (o *GoldpingerAPI) Serve(builder middleware.Builder) http.Handler {
if o.Middleware != nil {
return o.Middleware(builder)
}
if o.useSwaggerUI {
return o.context.APIHandlerSwaggerUI(builder)
}
return o.context.APIHandler(builder)
}

View File

@@ -29,7 +29,7 @@ func NewHealthz(ctx *middleware.Context, handler HealthzHandler) *Healthz {
return &Healthz{Context: ctx, Handler: handler}
}
/*Healthz swagger:route GET /healthz healthz
/* Healthz swagger:route GET /healthz healthz
The healthcheck endpoint provides detailed information about the health of a web service. If each of the components required by the service are healthy, then the service is considered healthy and will return a 200 OK response. If any of the components needed by the service are unhealthy, then a 503 Service Unavailable response will be provided.
@@ -42,17 +42,15 @@ type Healthz struct {
func (o *Healthz) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
r = rCtx
*r = *rCtx
}
var Params = NewHealthzParams()
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -13,7 +13,8 @@ import (
)
// NewHealthzParams creates a new HealthzParams object
// no default values defined in spec.
//
// There are no default values defined in the spec.
func NewHealthzParams() HealthzParams {
return HealthzParams{}

View File

@@ -29,7 +29,7 @@ func NewPing(ctx *middleware.Context, handler PingHandler) *Ping {
return &Ping{Context: ctx, Handler: handler}
}
/*Ping swagger:route GET /ping ping
/* Ping swagger:route GET /ping ping
return query stats
@@ -42,17 +42,15 @@ type Ping struct {
func (o *Ping) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
r = rCtx
*r = *rCtx
}
var Params = NewPingParams()
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View File

@@ -13,7 +13,8 @@ import (
)
// NewPingParams creates a new PingParams object
// no default values defined in spec.
//
// There are no default values defined in the spec.
func NewPingParams() PingParams {
return PingParams{}

View File

@@ -305,9 +305,6 @@ func (s *Server) Serve() (err error) {
s.Fatalf("no certificate was configured for TLS")
}
// must have at least one certificate or panics
httpsServer.TLSConfig.BuildNameToCertificate()
configureServer(httpsServer, "https", s.httpsServerL.Addr().String())
servers = append(servers, httpsServer)

View File

@@ -213,6 +213,7 @@ var loadingDialog = function(enable){
var global_data = undefined;
var s; // the sigma graph
var main = function(timeout){
timeout = timeout || Number($("#timeout").val()) || 5.0;
@@ -229,7 +230,6 @@ var main = function(timeout){
// prepare nodes
var nodes = [];
var dnsCheckNodes = [];
var podIPs = [];
var resp = data.responses;
for (let podIP in resp) {
@@ -284,39 +284,44 @@ var main = function(timeout){
})
})
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: {
var probeResultsNodes = [];
if ('probeResults' in data) {
var yoffset = 0;
for (let checkedHost in data.probeResults) {
let value = data.probeResults[checkedHost];
var allOk = true;
for (let pod in value) {
for (var i = 0; i < value[pod].length; i++){
var elapsed = 0;
var podData = value[pod][i];
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,
}
});
"isprobeResultsNode": true,
}
});
}
}
value["OK"] = allOk
dnsCheckNodes.push({
"label": checkedHost,
"id": checkedHost,
"x": 0,
"y": 0,
_data: value,
});
}
probeResultsNodes.push({
"label": checkedHost,
"id": checkedHost,
"x": 0,
"y": 0,
_data: value,
});
}
}
// build the actual graph
@@ -351,7 +356,7 @@ var main = function(timeout){
});
// generate any dns nodes on the graph
dnsCheckNodes.forEach(function(node, i, a){
probeResultsNodes.forEach(function(node, i, a){
node.x = 2;
node.y = (0.6 * i / a.length) - 0.8;
node.size = 10;
@@ -359,7 +364,6 @@ var main = function(timeout){
if (!node._data.OK) {
node.color = "red";
}
//console.log(node);
s.graph.addNode(node);
});
@@ -374,7 +378,7 @@ var main = function(timeout){
if (!edge._data.OK) {
color = "red";
}
if ("isDNSCheckNode" in edge._data) {
if ("isprobeResultsNode" in edge._data) {
type = "dashed";
}
var edge = {

View File

@@ -12,17 +12,21 @@ definitions:
type: integer
ping:
type: integer
DnsResult:
ProbeResult:
properties:
response-time-ms:
type: number
format: int64
error:
type: string
DnsResults:
protocol:
type: string
ProbeResults:
type: object
additionalProperties:
$ref: '#/definitions/DnsResult'
type: array
items:
$ref: '#/definitions/ProbeResult'
PingResults:
type: object
properties:
@@ -60,8 +64,8 @@ definitions:
CheckResults:
type: object
properties:
dnsResults:
$ref: '#/definitions/DnsResults'
probeResults:
$ref: '#/definitions/ProbeResults'
podResults:
type: object
additionalProperties:
@@ -110,10 +114,10 @@ definitions:
podIP:
type: string
format: ipv4
dnsResults:
probeResults:
type: object
additionalProperties:
$ref: '#/definitions/DnsResults'
$ref: '#/definitions/ProbeResults'
responses:
type: object
additionalProperties:
@@ -130,6 +134,31 @@ definitions:
duration-ns:
type: integer
format: int64
ClusterHealthResults:
type: object
properties:
OK:
type: boolean
default: false
nodesHealthy:
type: array
items:
type: string
nodesUnhealthy:
type: array
items:
type: string
nodesTotal:
type: integer
format: int64
generated-at:
type: string
format: date-time
duration-ns:
type: integer
format: int64
required:
- OK
paths:
/ping:
get:
@@ -167,6 +196,21 @@ paths:
description: Success, return response
schema:
$ref: '#/definitions/CheckAllResults'
/cluster_health:
get:
description: Checks the full graph. Returns a binary OK or not OK.
produces:
- application/json
operationId: clusterHealth
responses:
200:
description: Healthy cluster
schema:
$ref: '#/definitions/ClusterHealthResults'
418:
description: Unhealthy cluster
schema:
$ref: '#/definitions/ClusterHealthResults'
/healthz:
get:
description: The healthcheck endpoint provides detailed information about