mirror of
https://github.com/bloomberg/goldpinger.git
synced 2026-04-06 10:26:51 +00:00
Compare commits
4 Commits
goldpinger
...
gh-pages
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
254ccf4eac | ||
|
|
14e5375d48 | ||
|
|
71e6ac8917 | ||
|
|
4ef1985782 |
33
.github/workflows/helm-publish.yaml
vendored
33
.github/workflows/helm-publish.yaml
vendored
@@ -1,33 +0,0 @@
|
||||
name: Helm Publish
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
helm_publish:
|
||||
# depending on default permission settings for your org (contents being read-only or read-write for workloads), you will have to add permissions
|
||||
# see: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token
|
||||
permissions:
|
||||
contents: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Configure Git
|
||||
run: |
|
||||
git config user.name "$GITHUB_ACTOR"
|
||||
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
|
||||
|
||||
- name: Install Helm
|
||||
uses: azure/setup-helm@v4
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
- name: Run chart-releaser
|
||||
uses: helm/chart-releaser-action@v1.7.0
|
||||
env:
|
||||
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
74
.github/workflows/helm-test.yaml
vendored
74
.github/workflows/helm-test.yaml
vendored
@@ -1,74 +0,0 @@
|
||||
name: Helm Test
|
||||
on:
|
||||
pull_request:
|
||||
jobs:
|
||||
helm_test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
|
||||
- name: Install Tools
|
||||
shell: bash
|
||||
id: tool-versions
|
||||
env:
|
||||
TILT_TOOL_CTLPTL_VERSION: "0.8.28"
|
||||
TILT_TOOL_KIND_VERSION: "0.23.0"
|
||||
TILT_TOOL_KUBECTL_VERSION: "1.30.0"
|
||||
TILT_TOOL_HELM_VERSION: "3.14.4"
|
||||
TILT_TOOL_TILT_VERSION: "0.33.13"
|
||||
run: |
|
||||
|
||||
# Create Tools Directory
|
||||
TOOLS_DIR=/opt/helm_tools
|
||||
mkdir -p "${TOOLS_DIR}"
|
||||
|
||||
# Download ctlptl
|
||||
echo "Downloading ctlptl"
|
||||
curl -fsSL https://github.com/tilt-dev/ctlptl/releases/download/v${TILT_TOOL_CTLPTL_VERSION}/ctlptl.${TILT_TOOL_CTLPTL_VERSION}.linux.x86_64.tar.gz | sudo tar -xzv -C "${TOOLS_DIR}" ctlptl
|
||||
|
||||
# Download kind
|
||||
echo "Downloading kind"
|
||||
curl -fsSL https://kind.sigs.k8s.io/dl/v${TILT_TOOL_KIND_VERSION}/kind-linux-amd64 -o "${TOOLS_DIR}/kind"
|
||||
|
||||
# Download kubectl
|
||||
echo "Downloading kubectl"
|
||||
curl -fsSL https://dl.k8s.io/release/v${TILT_TOOL_KUBECTL_VERSION}/bin/linux/amd64/kubectl -o "${TOOLS_DIR}/kubectl"
|
||||
|
||||
# Download helm
|
||||
echo "Downloading helm"
|
||||
curl -fsSL https://get.helm.sh/helm-v${TILT_TOOL_HELM_VERSION}-linux-amd64.tar.gz | tar -xzv -C "${TOOLS_DIR}" --strip-components=1 linux-amd64/helm
|
||||
|
||||
# Download tilt
|
||||
echo "Downloading tilt"
|
||||
curl -fsSL https://github.com/tilt-dev/tilt/releases/download/v${TILT_TOOL_TILT_VERSION}/tilt.${TILT_TOOL_TILT_VERSION}.linux.x86_64.tar.gz | tar -xzv -C "${TOOLS_DIR}" tilt
|
||||
|
||||
# Make the binaries runnable
|
||||
echo "Making binaries executable"
|
||||
sudo chmod -R +x "${TOOLS_DIR}"
|
||||
|
||||
# Add tools to path
|
||||
echo "PATH=${PATH}:${TOOLS_DIR}" >> $GITHUB_ENV
|
||||
|
||||
- name: Start Kind Cluster
|
||||
shell: bash
|
||||
run: |
|
||||
ctlptl apply -f kind.yaml
|
||||
|
||||
- name: Run Tilt Tests
|
||||
shell: bash
|
||||
run: |
|
||||
tilt ci --debug --output-snapshot-on-exit=/tmp/tilt-snapshot.json
|
||||
|
||||
- name: Upload Tilt Snapshot
|
||||
if: success() || failure()
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: tilt-snapshot
|
||||
path: |
|
||||
/tmp/tilt-snapshot.json
|
||||
9
.github/workflows/main.yml
vendored
9
.github/workflows/main.yml
vendored
@@ -15,9 +15,9 @@ jobs:
|
||||
packages: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
|
||||
@@ -45,6 +45,7 @@ jobs:
|
||||
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
|
||||
@@ -62,13 +63,13 @@ jobs:
|
||||
org.opencontainers.image.vendor=${{ github.repository_owner }}
|
||||
|
||||
- name: Build regular image
|
||||
uses: docker/bake-action@v6
|
||||
uses: docker/bake-action@v4
|
||||
with:
|
||||
targets: ci
|
||||
push: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
|
||||
files: |
|
||||
./docker-bake.hcl
|
||||
cwd://${{ steps.meta.outputs.bake-file }}
|
||||
${{ steps.meta.outputs.bake-file }}
|
||||
|
||||
# https://github.com/docker/buildx/issues/2105
|
||||
- name: Create manifest
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -91,4 +91,3 @@ ENV/
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
.secrets
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
ARG WINDOWS_BASE_IMAGE=mcr.microsoft.com/windows/nanoserver:ltcs2022
|
||||
|
||||
FROM --platform=$BUILDPLATFORM golang:1.25 as builder
|
||||
FROM --platform=$BUILDPLATFORM golang:1.22 as builder
|
||||
ARG TARGETARCH
|
||||
ARG TARGETOS
|
||||
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,5 +1,5 @@
|
||||
name ?= goldpinger
|
||||
version ?= v3.11.0
|
||||
version ?= v3.10.1
|
||||
bin ?= goldpinger
|
||||
pkg ?= "github.com/bloomberg/goldpinger"
|
||||
tag = $(name):$(version)
|
||||
|
||||
71
README.md
71
README.md
@@ -1,7 +1,6 @@
|
||||
# Goldpinger
|
||||
|
||||
[](https://github.com/bloomberg/goldpinger/actions/workflows/publish.yml)
|
||||
[](https://deepwiki.com/bloomberg/goldpinger)
|
||||
|
||||
__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.
|
||||
@@ -25,7 +24,6 @@ Oh, and it gives you the graph below for your cluster. Check out the [video expl
|
||||
- [Authentication with Kubernetes API](#authentication-with-kubernetes-api)
|
||||
- [Example YAML](#example-yaml)
|
||||
- [Note on DNS](#note-on-dns)
|
||||
- [UDP probe for packet loss, hop count, and RTT](#udp-probe-for-packet-loss-hop-count-and-rtt)
|
||||
- [Usage](#usage)
|
||||
- [UI](#ui)
|
||||
- [API](#api)
|
||||
@@ -103,25 +101,14 @@ docker push $(namespace="docker.io/myhandle/" make version)
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
`Goldpinger` works by asking `Kubernetes` for pods with particular labels (`app=goldpinger`). While you can deploy `Goldpinger` in a variety of ways, it works very nicely as a `DaemonSet` out of the box.
|
||||
|
||||
### Helm Installation
|
||||
Goldpinger can be installed via [Helm](https://helm.sh/) using the following:
|
||||
|
||||
```
|
||||
helm repo add goldpinger https://bloomberg.github.io/goldpinger
|
||||
helm repo update
|
||||
helm install goldpinger goldpinger/goldpinger
|
||||
```
|
||||
|
||||
### Manual Installation
|
||||
`Goldpinger` can be installed manually via configuration similar to the following:
|
||||
|
||||
#### Authentication with Kubernetes API
|
||||
### Authentication with Kubernetes API
|
||||
|
||||
`Goldpinger` supports using a `kubeconfig` (specify with `--kubeconfig-path`) or service accounts.
|
||||
|
||||
#### Example YAML
|
||||
### Example YAML
|
||||
|
||||
Here's an example of what you can do (using the in-cluster authentication to `Kubernetes` apiserver).
|
||||
|
||||
@@ -288,56 +275,10 @@ Instances can also be configured to do simple TCP or HTTP checks on external tar
|
||||
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.
|
||||
the timeouts for the TCP, DNS and HTTP checks can be configured via `TCP_TARGETS_TIMEOUT`, `DNS_TARGETS_TIMEOUT` and `HTTP_TARGETS_TIMEOUT` respectively.
|
||||
|
||||

|
||||
|
||||
### UDP probe for packet loss, hop count, and RTT
|
||||
|
||||
In natively routed Kubernetes environments (e.g. Cilium, Calico in BGP mode), the existing HTTP ping can mask network issues: TCP retransmits hide packet loss, and HTTP latency includes the 3-way handshake, TLS, and application overhead. The UDP probe gives you visibility into the actual network layer.
|
||||
|
||||
When enabled, each goldpinger pod runs a UDP echo listener. During each ping cycle, the prober sends a configurable number of sequenced UDP packets to each peer; the peer echoes them back. From the replies, goldpinger computes:
|
||||
|
||||
- **Packet loss** — percentage of packets that were not returned, surfacing degraded links before they impact applications
|
||||
- **Hop count** — estimated from the IPv4 TTL or IPv6 HopLimit on received replies, useful for detecting asymmetric routing or unexpected topology changes
|
||||
- **UDP RTT** — average round-trip time with sub-millisecond precision, isolating network latency from TCP/HTTP overhead
|
||||
|
||||
The feature is disabled by default and can be enabled with the following environment variables:
|
||||
|
||||
```sh
|
||||
UDP_ENABLED=true # enable UDP probing and echo listener
|
||||
UDP_PORT=6969 # listener port (default: 6969)
|
||||
UDP_PACKET_COUNT=10 # packets per probe (default: 10)
|
||||
UDP_PACKET_SIZE=64 # bytes per packet (default: 64)
|
||||
UDP_TIMEOUT=1s # probe timeout (default: 1s)
|
||||
```
|
||||
|
||||
Or via the Helm chart:
|
||||
|
||||
```yaml
|
||||
goldpinger:
|
||||
udp:
|
||||
enabled: true
|
||||
port: 6969
|
||||
```
|
||||
|
||||
This adds three Prometheus metrics:
|
||||
|
||||
```sh
|
||||
goldpinger_peers_loss_pct # gauge: UDP packet loss percentage (0-100)
|
||||
goldpinger_peers_hop_count # gauge: estimated hop count
|
||||
goldpinger_peers_udp_rtt_s # histogram: UDP round-trip time in seconds
|
||||
goldpinger_udp_errors_total # counter: UDP probe errors
|
||||
```
|
||||
|
||||
Links with partial loss are shown as yellow edges in the graph UI, and edge labels display the UDP RTT instead of HTTP latency when available.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
No new dependencies are required (`golang.org/x/net` is already in go.mod), and no additional container capabilities are needed.
|
||||
|
||||
## Usage
|
||||
|
||||
### UI
|
||||
@@ -364,12 +305,10 @@ These are probably the droids you are looking for:
|
||||
|
||||
```sh
|
||||
goldpinger_peers_response_time_s_*
|
||||
goldpinger_peers_response_time_s_*
|
||||
goldpinger_nodes_health_total
|
||||
goldpinger_stats_total
|
||||
goldpinger_errors_total
|
||||
goldpinger_peers_loss_pct # (UDP probe, when enabled)
|
||||
goldpinger_peers_hop_count # (UDP probe, when enabled)
|
||||
goldpinger_peers_udp_rtt_s_* # (UDP probe, when enabled)
|
||||
```
|
||||
|
||||
### Grafana
|
||||
|
||||
30
Tiltfile
30
Tiltfile
@@ -1,30 +0,0 @@
|
||||
# -*- mode: bazel-starlark -*-
|
||||
|
||||
# Build the image
|
||||
docker_build('goldpinger-local', '.')
|
||||
|
||||
# Deploy with Helm
|
||||
k8s_yaml(
|
||||
helm(
|
||||
'charts/goldpinger',
|
||||
set = [
|
||||
# Set the image to the one built by Tilt
|
||||
'image.repository=goldpinger-local',
|
||||
],
|
||||
)
|
||||
)
|
||||
|
||||
# Track Goldpinger Resource
|
||||
k8s_resource(
|
||||
'chart-goldpinger',
|
||||
port_forwards = [8080],
|
||||
)
|
||||
|
||||
# Validate that all 2 nodes can talk to eachother
|
||||
local_resource(
|
||||
'check_reachability',
|
||||
cmd='./extras/check_reachability.sh 2',
|
||||
resource_deps = [
|
||||
'chart-goldpinger',
|
||||
],
|
||||
)
|
||||
@@ -1,23 +0,0 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
|
||||
OWNERS
|
||||
@@ -1,8 +0,0 @@
|
||||
apiVersion: v1
|
||||
name: goldpinger
|
||||
appVersion: "3.11.0"
|
||||
version: 1.1.0
|
||||
description: Goldpinger is a tool to help debug, troubleshoot and visualize network connectivity and slowness issues.
|
||||
home: https://github.com/bloomberg/goldpinger
|
||||
sources:
|
||||
- https://github.com/bloomberg/goldpinger
|
||||
@@ -1,62 +0,0 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "goldpinger.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "goldpinger.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "goldpinger.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "goldpinger.labels" -}}
|
||||
helm.sh/chart: {{ include "goldpinger.chart" . }}
|
||||
{{ include "goldpinger.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "goldpinger.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "goldpinger.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "goldpinger.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "goldpinger.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,12 +0,0 @@
|
||||
{{- if and .Values.rbac.create .Values.rbac.clusterscoped }}
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: {{ include "goldpinger.fullname" . }}-clusterrole
|
||||
labels:
|
||||
{{- include "goldpinger.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["list"]
|
||||
{{- end }}
|
||||
@@ -1,16 +0,0 @@
|
||||
{{- if and .Values.rbac.create .Values.rbac.clusterscoped }}
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: {{ include "goldpinger.fullname" . }}-clusterrolebinding
|
||||
labels:
|
||||
{{- include "goldpinger.labels" . | nindent 4 }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "goldpinger.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: {{ include "goldpinger.fullname" . }}-clusterrole
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
{{- end }}
|
||||
@@ -1,8 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "goldpinger.fullname" . }}-zap
|
||||
labels:
|
||||
{{- include "goldpinger.labels" . | nindent 4 }}
|
||||
data:
|
||||
zap.json: {{ .Values.goldpinger.zapConfig | toJson }}
|
||||
@@ -1,114 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: {{ include "goldpinger.fullname" . }}
|
||||
labels:
|
||||
{{- include "goldpinger.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- with .Values.updateStrategy }}
|
||||
updateStrategy:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "goldpinger.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{ toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "goldpinger.selectorLabels" . | nindent 8 }}
|
||||
{{- with .Values.podLabels }}
|
||||
{{ toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
priorityClassName: {{ .Values.priorityClassName }}
|
||||
serviceAccountName: {{ include "goldpinger.serviceAccountName" . }}
|
||||
{{- if .Values.image.pullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- range .Values.image.pullSecrets }}
|
||||
- name: {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: goldpinger-daemon
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
volumeMounts:
|
||||
- name: zap
|
||||
mountPath: /config
|
||||
env:
|
||||
- name: HOSTNAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: HOST
|
||||
value: "0.0.0.0"
|
||||
- name: PORT
|
||||
value: "{{ .Values.goldpinger.port }}"
|
||||
- name: LABEL_SELECTOR
|
||||
value: "app.kubernetes.io/name={{ include "goldpinger.name" . }}"
|
||||
{{- if .Values.goldpinger.udp.enabled }}
|
||||
- name: UDP_ENABLED
|
||||
value: "true"
|
||||
- name: UDP_PORT
|
||||
value: "{{ .Values.goldpinger.udp.port }}"
|
||||
{{- end }}
|
||||
{{- if .Values.extraEnv -}}
|
||||
{{ toYaml .Values.extraEnv | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.containerSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.goldpinger.port }}
|
||||
protocol: TCP
|
||||
{{- range $k := .Values.extraEnv }}
|
||||
{{- if and (eq $k.name "USE_HOST_IP") (eq $k.value "true") }}
|
||||
hostPort: {{ $.Values.goldpinger.port }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.goldpinger.udp.enabled }}
|
||||
- name: udp-probe
|
||||
containerPort: {{ .Values.goldpinger.udp.port }}
|
||||
protocol: UDP
|
||||
{{- end }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
volumes:
|
||||
- name: zap
|
||||
configMap:
|
||||
name: {{ include "goldpinger.fullname" . }}-zap
|
||||
{{- range $k := .Values.extraEnv }}
|
||||
{{- if and (eq $k.name "USE_HOST_IP") (eq $k.value "true") }}
|
||||
hostNetwork: true
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -1,61 +0,0 @@
|
||||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "goldpinger.fullname" . -}}
|
||||
{{- $svcPort := .Values.service.port -}}
|
||||
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{- include "goldpinger.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
|
||||
pathType: {{ .pathType }}
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $fullName }}
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- else }}
|
||||
serviceName: {{ $fullName }}
|
||||
servicePort: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,19 +0,0 @@
|
||||
{{- if .Values.prometheusRule.enabled }}
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: PrometheusRule
|
||||
metadata:
|
||||
name: {{ template "goldpinger.fullname" . }}
|
||||
{{- if .Values.prometheusRule.namespace }}
|
||||
namespace: {{ .Values.prometheusRule.namespace }}
|
||||
{{- else }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "goldpinger.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- with .Values.prometheusRule.rules }}
|
||||
groups:
|
||||
- name: {{ template "goldpinger.name" $ }}
|
||||
rules: {{- tpl (toYaml .) $ | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,20 +0,0 @@
|
||||
{{- if or .Values.podSecurityPolicy.enabled (not .Values.rbac.clusterscoped) }}
|
||||
kind: Role
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: {{ include "goldpinger.fullname" . }}-pod-security-policy
|
||||
labels:
|
||||
{{- include "goldpinger.labels" . | nindent 4 }}
|
||||
rules:
|
||||
{{- if not .Values.rbac.clusterscoped }}
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["list"]
|
||||
{{- end }}
|
||||
{{- if .Values.podSecurityPolicy.enabled }}
|
||||
- apiGroups: ["extensions"]
|
||||
resources: ["podsecuritypolicies"]
|
||||
resourceNames: [{{ .Values.podSecurityPolicy.policyName | quote }}]
|
||||
verbs: ["use"]
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,16 +0,0 @@
|
||||
{{- if or .Values.podSecurityPolicy.enabled (not .Values.rbac.clusterscoped) }}
|
||||
kind: RoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: {{ include "goldpinger.fullname" . }}-pod-security-policy
|
||||
labels:
|
||||
{{- include "goldpinger.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: {{ include "goldpinger.fullname" . }}-pod-security-policy
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "goldpinger.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end }}
|
||||
@@ -1,32 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "goldpinger.fullname" . }}
|
||||
labels:
|
||||
{{- include "goldpinger.labels" . | nindent 4 }}
|
||||
{{- with .Values.service.labels }}
|
||||
{{ toYaml . | indent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.service.annotations }}
|
||||
annotations:
|
||||
{{ toYaml . | indent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: {{ .Values.goldpinger.port }}
|
||||
protocol: TCP
|
||||
name: http
|
||||
{{- if .Values.goldpinger.udp.enabled }}
|
||||
- port: {{ .Values.goldpinger.udp.port }}
|
||||
targetPort: {{ .Values.goldpinger.udp.port }}
|
||||
protocol: UDP
|
||||
name: udp-probe
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "goldpinger.selectorLabels" . | nindent 4 }}
|
||||
{{- if .Values.service.loadBalancerSourceRanges }}
|
||||
loadBalancerSourceRanges:
|
||||
{{- toYaml .Values.service.loadBalancerSourceRanges | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -1,8 +0,0 @@
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "goldpinger.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "goldpinger.labels" . | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -1,32 +0,0 @@
|
||||
{{- if .Values.serviceMonitor.enabled }}
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
name: {{ include "goldpinger.fullname" . }}
|
||||
{{- if .Values.serviceMonitor.namespace }}
|
||||
namespace: {{ .Values.serviceMonitor.namespace }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "goldpinger.labels" . | nindent 4 }}
|
||||
{{- range $key, $value := .Values.serviceMonitor.selector }}
|
||||
{{ $key }}: {{ $value | quote }}
|
||||
{{- end }}
|
||||
spec:
|
||||
endpoints:
|
||||
- port: http
|
||||
interval: {{ .Values.serviceMonitor.interval }}
|
||||
{{- if .Values.serviceMonitor.honorLabels }}
|
||||
honorLabels: true
|
||||
{{- end }}
|
||||
{{- with .Values.serviceMonitor.metricRelabelings }}
|
||||
metricRelabelings:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
jobLabel: name
|
||||
namespaceSelector:
|
||||
matchNames:
|
||||
- {{ .Release.Namespace }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "goldpinger.selectorLabels" . | nindent 6 }}
|
||||
{{- end -}}
|
||||
@@ -1,169 +0,0 @@
|
||||
# Default values for goldpinger.
|
||||
# This is a YAML-formatted file.
|
||||
# Declare variables to be passed into your templates.
|
||||
image:
|
||||
repository: bloomberg/goldpinger
|
||||
# Overrides the image tag whose default is the chart appVersion.
|
||||
tag: ""
|
||||
pullPolicy: IfNotPresent
|
||||
## Optionally specify an array of imagePullSecrets.
|
||||
## Secrets must be manually created in the namespace.
|
||||
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
|
||||
##
|
||||
# pullSecrets:
|
||||
# - myRegistryKeySecretName
|
||||
|
||||
rbac:
|
||||
create: true
|
||||
clusterscoped: true
|
||||
|
||||
serviceAccount:
|
||||
create: true
|
||||
name:
|
||||
|
||||
goldpinger:
|
||||
port: 8080
|
||||
udp:
|
||||
enabled: false
|
||||
port: 6969
|
||||
zapConfig: |
|
||||
{
|
||||
"level": "info",
|
||||
"encoding": "json",
|
||||
"outputPaths": [
|
||||
"stdout"
|
||||
],
|
||||
"errorOutputPaths": [
|
||||
"stderr"
|
||||
],
|
||||
"initialFields": {
|
||||
},
|
||||
"encoderConfig": {
|
||||
"messageKey": "message",
|
||||
"levelKey": "level",
|
||||
"levelEncoder": "lowercase",
|
||||
"timeKey": "ts",
|
||||
"timeEncoder": "ISO8601",
|
||||
"callerKey": "caller",
|
||||
"callerEncoder": "Short"
|
||||
}
|
||||
}
|
||||
|
||||
extraEnv: []
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8081
|
||||
annotations: {}
|
||||
labels: {}
|
||||
loadBalancerSourceRanges: {}
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
hosts:
|
||||
- host: chart-example.local
|
||||
paths:
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
|
||||
## Set a priorityClassName for the pod. If left blank a default priority will be set.
|
||||
priorityClassName:
|
||||
|
||||
resources: {}
|
||||
# We usually recommend not to specify default resources and to leave this as a conscious
|
||||
# choice for the user. This also increases chances charts run on environments with little
|
||||
# resources, such as Minikube. If you do want to specify resources, uncomment the following
|
||||
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||
# limits:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podLabels: {}
|
||||
|
||||
updateStrategy: {}
|
||||
# type: RollingUpdate
|
||||
# rollingUpdate:
|
||||
# maxUnavailable: 1
|
||||
|
||||
## Node labels for pod assignment
|
||||
## Ref: https://kubernetes.io/docs/user-guide/node-selection/
|
||||
##
|
||||
nodeSelector: {}
|
||||
|
||||
## Tolerations for pod assignment
|
||||
## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
|
||||
##
|
||||
tolerations: []
|
||||
|
||||
## Affinity for pod assignment
|
||||
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
|
||||
##
|
||||
affinity: {}
|
||||
|
||||
## Enable this if pod security policy enabled in your cluster
|
||||
## It will bind ServiceAccount with unrestricted podSecurityPolicy
|
||||
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/
|
||||
podSecurityPolicy:
|
||||
enabled: false
|
||||
policyName: unrestricted-psp
|
||||
|
||||
## Set security context of the goldpinger container
|
||||
## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
|
||||
containerSecurityContext:
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsNonRoot: true
|
||||
|
||||
## Set security context of the pod
|
||||
## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
fsGroup: 2000
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
|
||||
serviceMonitor:
|
||||
enabled: false
|
||||
selector:
|
||||
prometheus: "kube-prometheus"
|
||||
# namespace: monitoring
|
||||
interval: 30s
|
||||
# honorLabels: true
|
||||
metricRelabelings: []
|
||||
# - action: drop
|
||||
# source_labels: [__name__]
|
||||
# regex: goldpinger_peers_response_time_s_bucket
|
||||
|
||||
## Custom PrometheusRule to be defined
|
||||
## ref: https://github.com/coreos/prometheus-operator#customresourcedefinitions
|
||||
prometheusRule:
|
||||
enabled: false
|
||||
rules:
|
||||
- alert: goldpinger_nodes_unhealthy
|
||||
expr: |
|
||||
sum(goldpinger_nodes_health_total{job="{{ template "goldpinger.fullname" . }}", status="unhealthy"})
|
||||
BY (instance, goldpinger_instance) > 0
|
||||
for: 5m
|
||||
annotations:
|
||||
description: |
|
||||
Goldpinger instance {{ "{{ $labels.goldpinger_instance }}" }} has been reporting unhealthy nodes for at least 5 minutes.
|
||||
summary: Instance {{ "{{ $labels.instance }}" }} down
|
||||
labels:
|
||||
severity: warning
|
||||
@@ -186,10 +186,6 @@ func main() {
|
||||
server.ConfigureAPI()
|
||||
goldpinger.StartUpdater()
|
||||
|
||||
if goldpinger.GoldpingerConfig.UDPEnabled {
|
||||
go goldpinger.StartUDPListener(goldpinger.GoldpingerConfig.UDPPort)
|
||||
}
|
||||
|
||||
logger.Info("All good, starting serving the API")
|
||||
|
||||
// serve API
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This is a simple script, used in the Tilt GitHub Action
|
||||
# to validate that all worker nodes can inter-communicate.
|
||||
|
||||
function print_help() {
|
||||
echo "Usage: $0 [EXPECTED_HOST_COUNT]"
|
||||
echo "Arguments:"
|
||||
echo " EXPECTED_HOST_COUNT: The number of expected hosts in the Goldpinger output."
|
||||
echo "Examples:"
|
||||
echo " $0 2"
|
||||
}
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Error: Invalid number of arguments."
|
||||
print_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [[ $1 =~ ^[0-9]+$ ]]; then
|
||||
echo "Error: EXPECTED_HOST_COUNT must be a number."
|
||||
print_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
expected_host_count=$1
|
||||
goldpinger_output=""
|
||||
retry_count=0
|
||||
host_count=0
|
||||
|
||||
while :; do
|
||||
if [ "$retry_count" -ge 20 ]; then
|
||||
echo "Error: Failed to fetch Goldpinger output after 10 attempts."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Sleeping for 8s..."
|
||||
let retry_count++
|
||||
sleep 8
|
||||
|
||||
echo "Attempt $((retry_count)) to fetch Goldpinger output."
|
||||
goldpinger_output=$(curl -s http://localhost:8080/check_all)
|
||||
echo "Goldpinger output: $goldpinger_output"
|
||||
|
||||
if [ "$goldpinger_output" == "null" ] || [ -z "$goldpinger_output" ]; then
|
||||
echo "Goldpinger output is null or empty, retrying..."
|
||||
continue
|
||||
fi
|
||||
|
||||
host_count=$(echo "$goldpinger_output" | jq '.hosts | length')
|
||||
if [ "$host_count" -ne "$expected_host_count" ]; then
|
||||
echo "Goldpinger has not identified all hosts, retrying..."
|
||||
continue
|
||||
fi
|
||||
|
||||
for host in $(echo $goldpinger_output | jq -r '.responses | keys[]'); do
|
||||
checksForPod=$(echo "$goldpinger_output" | jq -r --arg host "$host" '.responses[$host].response.podResults | length')
|
||||
if [ "$checksForPod" -ne "$expected_host_count" ]; then
|
||||
echo "Check for $host is not OK, retrying..."
|
||||
continue 2
|
||||
fi
|
||||
done
|
||||
|
||||
break
|
||||
done
|
||||
|
||||
all_hosts_can_talk=true
|
||||
for host in $(echo $goldpinger_output | jq -r '.responses | keys[]'); do
|
||||
for target in $(echo $goldpinger_output | jq -r --arg host $host '.responses[$host].response.podResults | keys[]'); do
|
||||
ok=$(echo $goldpinger_output | jq -r --arg host $host --arg target $target '.responses[$host].response.podResults[$target].OK')
|
||||
if [ "$ok" != "true" ]; then
|
||||
all_hosts_can_talk=false
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
if [[ $host_count -eq $expected_host_count ]] && [[ $all_hosts_can_talk == "true" ]]; then
|
||||
echo "Validation successful. There are $expected_host_count hosts and they can talk to each other."
|
||||
else
|
||||
echo "Validation failed. Expected $expected_host_count hosts but found $host_count, or not all hosts can talk to each other."
|
||||
echo "Goldpinger Output: $goldpinger_output"
|
||||
exit 1
|
||||
fi
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 191 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 456 KiB |
110
go.mod
110
go.mod
@@ -1,26 +1,26 @@
|
||||
module github.com/bloomberg/goldpinger/v3
|
||||
|
||||
go 1.25.0
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/cespare/xxhash v1.1.0
|
||||
github.com/go-openapi/errors v0.22.6
|
||||
github.com/go-openapi/loads v0.23.2
|
||||
github.com/go-openapi/runtime v0.29.2
|
||||
github.com/go-openapi/spec v0.22.3
|
||||
github.com/go-openapi/strfmt v0.25.0
|
||||
github.com/go-openapi/swag v0.25.4
|
||||
github.com/go-openapi/validate v0.25.1
|
||||
github.com/jessevdk/go-flags v1.6.1
|
||||
github.com/prometheus/client_golang v1.23.2
|
||||
github.com/go-openapi/errors v0.22.0
|
||||
github.com/go-openapi/loads v0.22.0
|
||||
github.com/go-openapi/runtime v0.28.0
|
||||
github.com/go-openapi/spec v0.21.0
|
||||
github.com/go-openapi/strfmt v0.23.0
|
||||
github.com/go-openapi/swag v0.23.0
|
||||
github.com/go-openapi/validate v0.24.0
|
||||
github.com/jessevdk/go-flags v1.5.0
|
||||
github.com/prometheus/client_golang v1.19.0
|
||||
github.com/stuartnelson3/go-rendezvous v0.2.0
|
||||
go.uber.org/zap v1.27.1
|
||||
golang.org/x/image v0.35.0
|
||||
golang.org/x/net v0.49.0
|
||||
k8s.io/api v0.35.0
|
||||
k8s.io/apimachinery v0.35.0
|
||||
k8s.io/client-go v0.35.0
|
||||
k8s.io/utils v0.0.0-20260108192941-914a6e750570
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/image v0.15.0
|
||||
golang.org/x/net v0.24.0
|
||||
k8s.io/api v0.29.3
|
||||
k8s.io/apimachinery v0.29.3
|
||||
k8s.io/client-go v0.29.3
|
||||
k8s.io/utils v0.0.0-20240310230437-4693a0247e57
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -29,69 +29,49 @@ require (
|
||||
github.com/cespare/xxhash/v2 v2.3.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.13.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.12.0 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/analysis v0.24.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.22.4 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.4 // indirect
|
||||
github.com/go-openapi/swag/cmdutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/conv v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/fileutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/jsonname v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/jsonutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/loading v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/mangling v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/netutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/stringutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/typeutils v0.25.4 // indirect
|
||||
github.com/go-openapi/swag/yamlutils v0.25.4 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
|
||||
github.com/go-openapi/analysis v0.23.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/gnostic-models v0.7.1 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // 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.9.1 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // 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.3-0.20250322232337-35a7c28c31ee // 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.6.2 // indirect
|
||||
github.com/prometheus/common v0.66.1 // indirect
|
||||
github.com/prometheus/procfs v0.19.2 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
go.mongodb.org/mongo-driver v1.17.7 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/otel v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.39.0 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.52.3 // indirect
|
||||
github.com/prometheus/procfs v0.13.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
go.mongodb.org/mongo-driver v1.15.0 // indirect
|
||||
go.opentelemetry.io/otel v1.25.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.25.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.25.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/oauth2 v0.34.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/sys v0.40.0 // indirect
|
||||
golang.org/x/term v0.39.0 // indirect
|
||||
golang.org/x/text v0.33.0 // indirect
|
||||
golang.org/x/time v0.14.0 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
|
||||
golang.org/x/oauth2 v0.19.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/term v0.19.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
google.golang.org/protobuf v1.33.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.130.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
|
||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect
|
||||
sigs.k8s.io/yaml v1.6.0 // indirect
|
||||
k8s.io/klog/v2 v2.120.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20240411171206-dc4e619f62f3 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
)
|
||||
|
||||
146
go.sum
146
go.sum
@@ -15,91 +15,39 @@ 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.12.0 h1:y2DdzBAURM29NFF94q6RaY4vjIH1rtwDapwQtU84iWk=
|
||||
github.com/emicklei/go-restful/v3 v3.12.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes=
|
||||
github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
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.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU=
|
||||
github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo=
|
||||
github.com/go-openapi/analysis v0.24.2 h1:6p7WXEuKy1llDgOH8FooVeO+Uq2za9qoAOq4ZN08B50=
|
||||
github.com/go-openapi/analysis v0.24.2/go.mod h1:x27OOHKANE0lutg2ml4kzYLoHGMKgRm1Cj2ijVOjJuE=
|
||||
github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w=
|
||||
github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE=
|
||||
github.com/go-openapi/errors v0.22.6 h1:eDxcf89O8odEnohIXwEjY1IB4ph5vmbUsBMsFNwXWPo=
|
||||
github.com/go-openapi/errors v0.22.6/go.mod h1:z9S8ASTUqx7+CP1Q8dD8ewGH/1JWFFLX/2PmAYNQLgk=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||
github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4=
|
||||
github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80=
|
||||
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
|
||||
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
|
||||
github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8=
|
||||
github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4=
|
||||
github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco=
|
||||
github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs=
|
||||
github.com/go-openapi/loads v0.23.2 h1:rJXAcP7g1+lWyBHC7iTY+WAF0rprtM+pm8Jxv1uQJp4=
|
||||
github.com/go-openapi/loads v0.23.2/go.mod h1:IEVw1GfRt/P2Pplkelxzj9BYFajiWOtY2nHZNj4UnWY=
|
||||
github.com/go-openapi/runtime v0.28.0 h1:gpPPmWSNGo214l6n8hzdXYhPuJcGtziTOgUpvsFWGIQ=
|
||||
github.com/go-openapi/runtime v0.28.0/go.mod h1:QN7OzcS+XuYmkQLw05akXk0jRH/eZ3kb18+1KwW9gyc=
|
||||
github.com/go-openapi/runtime v0.29.2 h1:UmwSGWNmWQqKm1c2MGgXVpC2FTGwPDQeUsBMufc5Yj0=
|
||||
github.com/go-openapi/runtime v0.29.2/go.mod h1:biq5kJXRJKBJxTDJXAa00DOTa/anflQPhT0/wmjuy+0=
|
||||
github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY=
|
||||
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
||||
github.com/go-openapi/spec v0.22.3 h1:qRSmj6Smz2rEBxMnLRBMeBWxbbOvuOoElvSvObIgwQc=
|
||||
github.com/go-openapi/spec v0.22.3/go.mod h1:iIImLODL2loCh3Vnox8TY2YWYJZjMAKYyLH2Mu8lOZs=
|
||||
github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c=
|
||||
github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4=
|
||||
github.com/go-openapi/strfmt v0.25.0 h1:7R0RX7mbKLa9EYCTHRcCuIPcaqlyQiWNPTXwClK0saQ=
|
||||
github.com/go-openapi/strfmt v0.25.0/go.mod h1:nNXct7OzbwrMY9+5tLX4I21pzcmE6ccMGXl3jFdPfn8=
|
||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU=
|
||||
github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ=
|
||||
github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4=
|
||||
github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0=
|
||||
github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4=
|
||||
github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU=
|
||||
github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y=
|
||||
github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk=
|
||||
github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI=
|
||||
github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag=
|
||||
github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA=
|
||||
github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY=
|
||||
github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s=
|
||||
github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE=
|
||||
github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48=
|
||||
github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg=
|
||||
github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0=
|
||||
github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg=
|
||||
github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8=
|
||||
github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0=
|
||||
github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw=
|
||||
github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE=
|
||||
github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw=
|
||||
github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc=
|
||||
github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58=
|
||||
github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ=
|
||||
github.com/go-openapi/validate v0.25.1 h1:sSACUI6Jcnbo5IWqbYHgjibrhhmt3vR6lCzKZnmAgBw=
|
||||
github.com/go-openapi/validate v0.25.1/go.mod h1:RMVyVFYte0gbSTaZ0N4KmTn6u/kClvAFp+mAVfS/DQc=
|
||||
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/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
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.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
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/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c=
|
||||
github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
|
||||
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=
|
||||
@@ -114,8 +62,6 @@ 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/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
|
||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||
github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4=
|
||||
github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPGBnNLMooyc=
|
||||
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=
|
||||
@@ -128,8 +74,6 @@ 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.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8=
|
||||
github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
|
||||
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=
|
||||
@@ -137,15 +81,12 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
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/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
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/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.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
|
||||
github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
|
||||
github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=
|
||||
github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg=
|
||||
github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
|
||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||
@@ -154,77 +95,47 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
|
||||
github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k=
|
||||
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
|
||||
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA=
|
||||
github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
|
||||
github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
|
||||
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
|
||||
github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o=
|
||||
github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g=
|
||||
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
|
||||
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
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.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stuartnelson3/go-rendezvous v0.2.0 h1:H5IexrsptBzCMQEjTRrNH20MVXGqpFf1JUCPglaxd6I=
|
||||
github.com/stuartnelson3/go-rendezvous v0.2.0/go.mod h1:njfgP6zISyRnZ3iQN13NSEILfSNLN4ysxBoGxHs5PJ0=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.mongodb.org/mongo-driver v1.15.0 h1:rJCKC8eEliewXjZGf0ddURtl7tTVy1TK3bfl0gkUSLc=
|
||||
go.mongodb.org/mongo-driver v1.15.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
|
||||
go.mongodb.org/mongo-driver v1.17.7 h1:a9w+U3Vt67eYzcfq3k/OAv284/uUUkL0uP75VE5rCOU=
|
||||
go.mongodb.org/mongo-driver v1.17.7/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k=
|
||||
go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg=
|
||||
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||
go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA=
|
||||
go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s=
|
||||
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
|
||||
go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM=
|
||||
go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I=
|
||||
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
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.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
|
||||
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
|
||||
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s=
|
||||
golang.org/x/image v0.21.0/go.mod h1:vUbsLavqK/W303ZroQQVKQ+Af3Yl6Uz1Ppu5J/cLz78=
|
||||
golang.org/x/image v0.35.0 h1:LKjiHdgMtO8z7Fh18nGY6KDcoEtVfsgLDPeLyguqb7I=
|
||||
golang.org/x/image v0.35.0/go.mod h1:MwPLTVgvxSASsxdLzKrl8BRFuyqMyGhLwmC+TO1Sybk=
|
||||
golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
|
||||
golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
|
||||
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/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
@@ -233,60 +144,42 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
||||
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
||||
golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg=
|
||||
golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8=
|
||||
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
||||
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/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.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
|
||||
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
|
||||
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
|
||||
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
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.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=
|
||||
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
||||
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.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
@@ -296,42 +189,19 @@ 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.29.3 h1:2ORfZ7+bGC3YJqGpV0KSDDEVf8hdGQ6A03/50vj8pmw=
|
||||
k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80=
|
||||
k8s.io/api v0.35.0 h1:iBAU5LTyBI9vw3L5glmat1njFK34srdLmktWwLTprlY=
|
||||
k8s.io/api v0.35.0/go.mod h1:AQ0SNTzm4ZAczM03QH42c7l3bih1TbAXYo0DkF8ktnA=
|
||||
k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU=
|
||||
k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU=
|
||||
k8s.io/apimachinery v0.35.0 h1:Z2L3IHvPVv/MJ7xRxHEtk6GoJElaAqDCCU0S6ncYok8=
|
||||
k8s.io/apimachinery v0.35.0/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=
|
||||
k8s.io/client-go v0.29.3 h1:R/zaZbEAxqComZ9FHeQwOh3Y1ZUs7FaHKZdQtIc2WZg=
|
||||
k8s.io/client-go v0.29.3/go.mod h1:tkDisCvgPfiRpxGnOORfkljmS+UrW+WtXAy2fTvXJB0=
|
||||
k8s.io/client-go v0.35.0 h1:IAW0ifFbfQQwQmga0UdoH0yvdqrbwMdq9vIFEhRpxBE=
|
||||
k8s.io/client-go v0.35.0/go.mod h1:q2E5AAyqcbeLGPdoRB+Nxe3KYTfPce1Dnu1myQdqz9o=
|
||||
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
|
||||
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20240411171206-dc4e619f62f3 h1:SbdLaI6mM6ffDSJCadEaD4IkuPzepLDGlkd2xV0t1uA=
|
||||
k8s.io/kube-openapi v0.0.0-20240411171206-dc4e619f62f3/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
|
||||
k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 h1:HhDfevmPS+OalTjQRKbTHppRIz01AWi8s45TMXStgYY=
|
||||
k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
|
||||
k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0gQBEuevE/AaBsHY=
|
||||
k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
k8s.io/utils v0.0.0-20260108192941-914a6e750570 h1:JT4W8lsdrGENg9W+YwwdLJxklIuKWdRm+BC+xt33FOY=
|
||||
k8s.io/utils v0.0.0-20260108192941-914a6e750570/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
|
||||
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/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
|
||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
||||
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
||||
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E=
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.1/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
||||
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
||||
|
||||
56
index.yaml
Normal file
56
index.yaml
Normal file
@@ -0,0 +1,56 @@
|
||||
apiVersion: v1
|
||||
entries:
|
||||
goldpinger:
|
||||
- apiVersion: v1
|
||||
appVersion: 3.11.0
|
||||
created: "2026-04-03T17:04:46.780018766Z"
|
||||
description: Goldpinger is a tool to help debug, troubleshoot and visualize network
|
||||
connectivity and slowness issues.
|
||||
digest: 65bd12dc539750be3324baad4a1f2df7e4db654d8c03ff831089a831e5965925
|
||||
home: https://github.com/bloomberg/goldpinger
|
||||
name: goldpinger
|
||||
sources:
|
||||
- https://github.com/bloomberg/goldpinger
|
||||
urls:
|
||||
- https://github.com/bloomberg/goldpinger/releases/download/goldpinger-1.1.0/goldpinger-1.1.0.tgz
|
||||
version: 1.1.0
|
||||
- apiVersion: v1
|
||||
appVersion: 3.10.3
|
||||
created: "2026-01-29T02:12:30.673237417Z"
|
||||
description: Goldpinger is a tool to help debug, troubleshoot and visualize network
|
||||
connectivity and slowness issues.
|
||||
digest: 3daef389a6b7ec17923cd670657ac1ea665cb3c2b0e65861e70c42b66a77976c
|
||||
home: https://github.com/bloomberg/goldpinger
|
||||
name: goldpinger
|
||||
sources:
|
||||
- https://github.com/bloomberg/goldpinger
|
||||
urls:
|
||||
- https://github.com/bloomberg/goldpinger/releases/download/goldpinger-1.0.2/goldpinger-1.0.2.tgz
|
||||
version: 1.0.2
|
||||
- apiVersion: v1
|
||||
appVersion: 3.10.2
|
||||
created: "2024-11-11T14:31:14.41363437Z"
|
||||
description: Goldpinger is a tool to help debug, troubleshoot and visualize network
|
||||
connectivity and slowness issues.
|
||||
digest: a6200043d5347782b034a83132a3a2bbd02d33e2a07a70309adb585d69b07b9a
|
||||
home: https://github.com/bloomberg/goldpinger
|
||||
name: goldpinger
|
||||
sources:
|
||||
- https://github.com/bloomberg/goldpinger
|
||||
urls:
|
||||
- https://github.com/bloomberg/goldpinger/releases/download/goldpinger-1.0.1/goldpinger-1.0.1.tgz
|
||||
version: 1.0.1
|
||||
- apiVersion: v1
|
||||
appVersion: 3.10.1
|
||||
created: "2024-05-14T14:47:00.150375039Z"
|
||||
description: Goldpinger is a tool to help debug, troublshoot and visualize network
|
||||
connectivity and slowness issues.
|
||||
digest: 1b5e214d6a052a4230d5e5825607f9283c3f94b974b9d4fca5594bcf5a07465d
|
||||
home: https://github.com/bloomberg/goldpinger
|
||||
name: goldpinger
|
||||
sources:
|
||||
- https://github.com/bloomberg/goldpinger
|
||||
urls:
|
||||
- https://github.com/bloomberg/goldpinger/releases/download/goldpinger-1.0.0/goldpinger-1.0.0.tgz
|
||||
version: 1.0.0
|
||||
generated: "2026-04-03T17:04:46.780032732Z"
|
||||
17
kind.yaml
17
kind.yaml
@@ -1,17 +0,0 @@
|
||||
apiVersion: ctlptl.dev/v1alpha1
|
||||
kind: Registry
|
||||
name: ctlptl-registry
|
||||
port: 20021
|
||||
---
|
||||
apiVersion: ctlptl.dev/v1alpha1
|
||||
kind: Cluster
|
||||
product: kind
|
||||
registry: ctlptl-registry
|
||||
kindV1Alpha4Cluster:
|
||||
name: goldpinger-test
|
||||
nodes:
|
||||
- role: control-plane
|
||||
- role: worker
|
||||
- role: worker
|
||||
networking:
|
||||
apiServerPort: 30022
|
||||
@@ -2,12 +2,14 @@
|
||||
|
||||
package client
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"github.com/bloomberg/goldpinger/v3/pkg/client/operations"
|
||||
"github.com/go-openapi/runtime"
|
||||
httptransport "github.com/go-openapi/runtime/client"
|
||||
"github.com/go-openapi/strfmt"
|
||||
|
||||
"github.com/bloomberg/goldpinger/v3/pkg/client/operations"
|
||||
)
|
||||
|
||||
// Default goldpinger HTTP client.
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
@@ -49,12 +52,10 @@ func NewCheckAllPodsParamsWithHTTPClient(client *http.Client) *CheckAllPodsParam
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
CheckAllPodsParams contains all the parameters to send to the API endpoint
|
||||
/* CheckAllPodsParams contains all the parameters to send to the API endpoint
|
||||
for the check all pods operation.
|
||||
|
||||
for the check all pods operation.
|
||||
|
||||
Typically these are written to a http.Request.
|
||||
Typically these are written to a http.Request.
|
||||
*/
|
||||
type CheckAllPodsParams struct {
|
||||
timeout time.Duration
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
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 (
|
||||
"encoding/json"
|
||||
stderrors "errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
@@ -20,7 +21,7 @@ type CheckAllPodsReader struct {
|
||||
}
|
||||
|
||||
// ReadResponse reads a server response into the received o.
|
||||
func (o *CheckAllPodsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (any, error) {
|
||||
func (o *CheckAllPodsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
|
||||
switch response.Code() {
|
||||
case 200:
|
||||
result := NewCheckAllPodsOK()
|
||||
@@ -29,7 +30,7 @@ func (o *CheckAllPodsReader) ReadResponse(response runtime.ClientResponse, consu
|
||||
}
|
||||
return result, nil
|
||||
default:
|
||||
return nil, runtime.NewAPIError("[GET /check_all] checkAllPods", 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())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,8 +39,7 @@ func NewCheckAllPodsOK() *CheckAllPodsOK {
|
||||
return &CheckAllPodsOK{}
|
||||
}
|
||||
|
||||
/*
|
||||
CheckAllPodsOK describes a response with status code 200, with default header values.
|
||||
/* CheckAllPodsOK describes a response with status code 200, with default header values.
|
||||
|
||||
Success, return response
|
||||
*/
|
||||
@@ -47,46 +47,9 @@ type CheckAllPodsOK struct {
|
||||
Payload *models.CheckAllResults
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this check all pods o k response has a 2xx status code
|
||||
func (o *CheckAllPodsOK) IsSuccess() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this check all pods o k response has a 3xx status code
|
||||
func (o *CheckAllPodsOK) IsRedirect() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsClientError returns true when this check all pods o k response has a 4xx status code
|
||||
func (o *CheckAllPodsOK) IsClientError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsServerError returns true when this check all pods o k response has a 5xx status code
|
||||
func (o *CheckAllPodsOK) IsServerError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCode returns true when this check all pods o k response a status code equal to that given
|
||||
func (o *CheckAllPodsOK) IsCode(code int) bool {
|
||||
return code == 200
|
||||
}
|
||||
|
||||
// Code gets the status code for the check all pods o k response
|
||||
func (o *CheckAllPodsOK) Code() int {
|
||||
return 200
|
||||
}
|
||||
|
||||
func (o *CheckAllPodsOK) Error() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /check_all][%d] checkAllPodsOK %s", 200, payload)
|
||||
return fmt.Sprintf("[GET /check_all][%d] checkAllPodsOK %+v", 200, o.Payload)
|
||||
}
|
||||
|
||||
func (o *CheckAllPodsOK) String() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /check_all][%d] checkAllPodsOK %s", 200, payload)
|
||||
}
|
||||
|
||||
func (o *CheckAllPodsOK) GetPayload() *models.CheckAllResults {
|
||||
return o.Payload
|
||||
}
|
||||
@@ -96,7 +59,7 @@ func (o *CheckAllPodsOK) readResponse(response runtime.ClientResponse, consumer
|
||||
o.Payload = new(models.CheckAllResults)
|
||||
|
||||
// response payload
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) {
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
@@ -49,12 +52,10 @@ func NewCheckServicePodsParamsWithHTTPClient(client *http.Client) *CheckServiceP
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
CheckServicePodsParams contains all the parameters to send to the API endpoint
|
||||
/* CheckServicePodsParams contains all the parameters to send to the API endpoint
|
||||
for the check service pods operation.
|
||||
|
||||
for the check service pods operation.
|
||||
|
||||
Typically these are written to a http.Request.
|
||||
Typically these are written to a http.Request.
|
||||
*/
|
||||
type CheckServicePodsParams struct {
|
||||
timeout time.Duration
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
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 (
|
||||
"encoding/json"
|
||||
stderrors "errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
@@ -20,7 +21,7 @@ type CheckServicePodsReader struct {
|
||||
}
|
||||
|
||||
// ReadResponse reads a server response into the received o.
|
||||
func (o *CheckServicePodsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (any, error) {
|
||||
func (o *CheckServicePodsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
|
||||
switch response.Code() {
|
||||
case 200:
|
||||
result := NewCheckServicePodsOK()
|
||||
@@ -29,7 +30,7 @@ func (o *CheckServicePodsReader) ReadResponse(response runtime.ClientResponse, c
|
||||
}
|
||||
return result, nil
|
||||
default:
|
||||
return nil, runtime.NewAPIError("[GET /check] checkServicePods", 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())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,8 +39,7 @@ func NewCheckServicePodsOK() *CheckServicePodsOK {
|
||||
return &CheckServicePodsOK{}
|
||||
}
|
||||
|
||||
/*
|
||||
CheckServicePodsOK describes a response with status code 200, with default header values.
|
||||
/* CheckServicePodsOK describes a response with status code 200, with default header values.
|
||||
|
||||
Success, return response
|
||||
*/
|
||||
@@ -47,46 +47,9 @@ type CheckServicePodsOK struct {
|
||||
Payload *models.CheckResults
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this check service pods o k response has a 2xx status code
|
||||
func (o *CheckServicePodsOK) IsSuccess() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this check service pods o k response has a 3xx status code
|
||||
func (o *CheckServicePodsOK) IsRedirect() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsClientError returns true when this check service pods o k response has a 4xx status code
|
||||
func (o *CheckServicePodsOK) IsClientError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsServerError returns true when this check service pods o k response has a 5xx status code
|
||||
func (o *CheckServicePodsOK) IsServerError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCode returns true when this check service pods o k response a status code equal to that given
|
||||
func (o *CheckServicePodsOK) IsCode(code int) bool {
|
||||
return code == 200
|
||||
}
|
||||
|
||||
// Code gets the status code for the check service pods o k response
|
||||
func (o *CheckServicePodsOK) Code() int {
|
||||
return 200
|
||||
}
|
||||
|
||||
func (o *CheckServicePodsOK) Error() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /check][%d] checkServicePodsOK %s", 200, payload)
|
||||
return fmt.Sprintf("[GET /check][%d] checkServicePodsOK %+v", 200, o.Payload)
|
||||
}
|
||||
|
||||
func (o *CheckServicePodsOK) String() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /check][%d] checkServicePodsOK %s", 200, payload)
|
||||
}
|
||||
|
||||
func (o *CheckServicePodsOK) GetPayload() *models.CheckResults {
|
||||
return o.Payload
|
||||
}
|
||||
@@ -96,7 +59,7 @@ func (o *CheckServicePodsOK) readResponse(response runtime.ClientResponse, consu
|
||||
o.Payload = new(models.CheckResults)
|
||||
|
||||
// response payload
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) {
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
@@ -49,12 +52,10 @@ func NewClusterHealthParamsWithHTTPClient(client *http.Client) *ClusterHealthPar
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ClusterHealthParams contains all the parameters to send to the API endpoint
|
||||
/* ClusterHealthParams contains all the parameters to send to the API endpoint
|
||||
for the cluster health operation.
|
||||
|
||||
for the cluster health operation.
|
||||
|
||||
Typically these are written to a http.Request.
|
||||
Typically these are written to a http.Request.
|
||||
*/
|
||||
type ClusterHealthParams struct {
|
||||
timeout time.Duration
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
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 (
|
||||
"encoding/json"
|
||||
stderrors "errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
@@ -20,7 +21,7 @@ type ClusterHealthReader struct {
|
||||
}
|
||||
|
||||
// ReadResponse reads a server response into the received o.
|
||||
func (o *ClusterHealthReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (any, error) {
|
||||
func (o *ClusterHealthReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
|
||||
switch response.Code() {
|
||||
case 200:
|
||||
result := NewClusterHealthOK()
|
||||
@@ -35,7 +36,7 @@ func (o *ClusterHealthReader) ReadResponse(response runtime.ClientResponse, cons
|
||||
}
|
||||
return nil, result
|
||||
default:
|
||||
return nil, runtime.NewAPIError("[GET /cluster_health] clusterHealth", 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())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +45,7 @@ func NewClusterHealthOK() *ClusterHealthOK {
|
||||
return &ClusterHealthOK{}
|
||||
}
|
||||
|
||||
/*
|
||||
ClusterHealthOK describes a response with status code 200, with default header values.
|
||||
/* ClusterHealthOK describes a response with status code 200, with default header values.
|
||||
|
||||
Healthy cluster
|
||||
*/
|
||||
@@ -53,46 +53,9 @@ type ClusterHealthOK struct {
|
||||
Payload *models.ClusterHealthResults
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this cluster health o k response has a 2xx status code
|
||||
func (o *ClusterHealthOK) IsSuccess() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this cluster health o k response has a 3xx status code
|
||||
func (o *ClusterHealthOK) IsRedirect() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsClientError returns true when this cluster health o k response has a 4xx status code
|
||||
func (o *ClusterHealthOK) IsClientError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsServerError returns true when this cluster health o k response has a 5xx status code
|
||||
func (o *ClusterHealthOK) IsServerError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCode returns true when this cluster health o k response a status code equal to that given
|
||||
func (o *ClusterHealthOK) IsCode(code int) bool {
|
||||
return code == 200
|
||||
}
|
||||
|
||||
// Code gets the status code for the cluster health o k response
|
||||
func (o *ClusterHealthOK) Code() int {
|
||||
return 200
|
||||
}
|
||||
|
||||
func (o *ClusterHealthOK) Error() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /cluster_health][%d] clusterHealthOK %s", 200, payload)
|
||||
return fmt.Sprintf("[GET /cluster_health][%d] clusterHealthOK %+v", 200, o.Payload)
|
||||
}
|
||||
|
||||
func (o *ClusterHealthOK) String() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /cluster_health][%d] clusterHealthOK %s", 200, payload)
|
||||
}
|
||||
|
||||
func (o *ClusterHealthOK) GetPayload() *models.ClusterHealthResults {
|
||||
return o.Payload
|
||||
}
|
||||
@@ -102,7 +65,7 @@ func (o *ClusterHealthOK) readResponse(response runtime.ClientResponse, consumer
|
||||
o.Payload = new(models.ClusterHealthResults)
|
||||
|
||||
// response payload
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) {
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -114,8 +77,7 @@ func NewClusterHealthIMATeapot() *ClusterHealthIMATeapot {
|
||||
return &ClusterHealthIMATeapot{}
|
||||
}
|
||||
|
||||
/*
|
||||
ClusterHealthIMATeapot describes a response with status code 418, with default header values.
|
||||
/* ClusterHealthIMATeapot describes a response with status code 418, with default header values.
|
||||
|
||||
Unhealthy cluster
|
||||
*/
|
||||
@@ -123,46 +85,9 @@ type ClusterHealthIMATeapot struct {
|
||||
Payload *models.ClusterHealthResults
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this cluster health i m a teapot response has a 2xx status code
|
||||
func (o *ClusterHealthIMATeapot) IsSuccess() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this cluster health i m a teapot response has a 3xx status code
|
||||
func (o *ClusterHealthIMATeapot) IsRedirect() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsClientError returns true when this cluster health i m a teapot response has a 4xx status code
|
||||
func (o *ClusterHealthIMATeapot) IsClientError() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IsServerError returns true when this cluster health i m a teapot response has a 5xx status code
|
||||
func (o *ClusterHealthIMATeapot) IsServerError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCode returns true when this cluster health i m a teapot response a status code equal to that given
|
||||
func (o *ClusterHealthIMATeapot) IsCode(code int) bool {
|
||||
return code == 418
|
||||
}
|
||||
|
||||
// Code gets the status code for the cluster health i m a teapot response
|
||||
func (o *ClusterHealthIMATeapot) Code() int {
|
||||
return 418
|
||||
}
|
||||
|
||||
func (o *ClusterHealthIMATeapot) Error() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /cluster_health][%d] clusterHealthIMATeapot %s", 418, payload)
|
||||
return fmt.Sprintf("[GET /cluster_health][%d] clusterHealthIMATeapot %+v", 418, o.Payload)
|
||||
}
|
||||
|
||||
func (o *ClusterHealthIMATeapot) String() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /cluster_health][%d] clusterHealthIMATeapot %s", 418, payload)
|
||||
}
|
||||
|
||||
func (o *ClusterHealthIMATeapot) GetPayload() *models.ClusterHealthResults {
|
||||
return o.Payload
|
||||
}
|
||||
@@ -172,7 +97,7 @@ func (o *ClusterHealthIMATeapot) readResponse(response runtime.ClientResponse, c
|
||||
o.Payload = new(models.ClusterHealthResults)
|
||||
|
||||
// response payload
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) {
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
@@ -49,12 +52,10 @@ func NewHealthzParamsWithHTTPClient(client *http.Client) *HealthzParams {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
HealthzParams contains all the parameters to send to the API endpoint
|
||||
/* HealthzParams contains all the parameters to send to the API endpoint
|
||||
for the healthz operation.
|
||||
|
||||
for the healthz operation.
|
||||
|
||||
Typically these are written to a http.Request.
|
||||
Typically these are written to a http.Request.
|
||||
*/
|
||||
type HealthzParams struct {
|
||||
timeout time.Duration
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
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 (
|
||||
"encoding/json"
|
||||
stderrors "errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
@@ -20,7 +21,7 @@ type HealthzReader struct {
|
||||
}
|
||||
|
||||
// ReadResponse reads a server response into the received o.
|
||||
func (o *HealthzReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (any, error) {
|
||||
func (o *HealthzReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
|
||||
switch response.Code() {
|
||||
case 200:
|
||||
result := NewHealthzOK()
|
||||
@@ -35,7 +36,7 @@ func (o *HealthzReader) ReadResponse(response runtime.ClientResponse, consumer r
|
||||
}
|
||||
return nil, result
|
||||
default:
|
||||
return nil, runtime.NewAPIError("[GET /healthz] healthz", 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())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +45,7 @@ func NewHealthzOK() *HealthzOK {
|
||||
return &HealthzOK{}
|
||||
}
|
||||
|
||||
/*
|
||||
HealthzOK describes a response with status code 200, with default header values.
|
||||
/* HealthzOK describes a response with status code 200, with default header values.
|
||||
|
||||
Health check report
|
||||
*/
|
||||
@@ -53,46 +53,9 @@ type HealthzOK struct {
|
||||
Payload *models.HealthCheckResults
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this healthz o k response has a 2xx status code
|
||||
func (o *HealthzOK) IsSuccess() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this healthz o k response has a 3xx status code
|
||||
func (o *HealthzOK) IsRedirect() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsClientError returns true when this healthz o k response has a 4xx status code
|
||||
func (o *HealthzOK) IsClientError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsServerError returns true when this healthz o k response has a 5xx status code
|
||||
func (o *HealthzOK) IsServerError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCode returns true when this healthz o k response a status code equal to that given
|
||||
func (o *HealthzOK) IsCode(code int) bool {
|
||||
return code == 200
|
||||
}
|
||||
|
||||
// Code gets the status code for the healthz o k response
|
||||
func (o *HealthzOK) Code() int {
|
||||
return 200
|
||||
}
|
||||
|
||||
func (o *HealthzOK) Error() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /healthz][%d] healthzOK %s", 200, payload)
|
||||
return fmt.Sprintf("[GET /healthz][%d] healthzOK %+v", 200, o.Payload)
|
||||
}
|
||||
|
||||
func (o *HealthzOK) String() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /healthz][%d] healthzOK %s", 200, payload)
|
||||
}
|
||||
|
||||
func (o *HealthzOK) GetPayload() *models.HealthCheckResults {
|
||||
return o.Payload
|
||||
}
|
||||
@@ -102,7 +65,7 @@ func (o *HealthzOK) readResponse(response runtime.ClientResponse, consumer runti
|
||||
o.Payload = new(models.HealthCheckResults)
|
||||
|
||||
// response payload
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) {
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -114,8 +77,7 @@ func NewHealthzServiceUnavailable() *HealthzServiceUnavailable {
|
||||
return &HealthzServiceUnavailable{}
|
||||
}
|
||||
|
||||
/*
|
||||
HealthzServiceUnavailable describes a response with status code 503, with default header values.
|
||||
/* HealthzServiceUnavailable describes a response with status code 503, with default header values.
|
||||
|
||||
Unhealthy service
|
||||
*/
|
||||
@@ -123,46 +85,9 @@ type HealthzServiceUnavailable struct {
|
||||
Payload *models.HealthCheckResults
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this healthz service unavailable response has a 2xx status code
|
||||
func (o *HealthzServiceUnavailable) IsSuccess() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this healthz service unavailable response has a 3xx status code
|
||||
func (o *HealthzServiceUnavailable) IsRedirect() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsClientError returns true when this healthz service unavailable response has a 4xx status code
|
||||
func (o *HealthzServiceUnavailable) IsClientError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsServerError returns true when this healthz service unavailable response has a 5xx status code
|
||||
func (o *HealthzServiceUnavailable) IsServerError() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IsCode returns true when this healthz service unavailable response a status code equal to that given
|
||||
func (o *HealthzServiceUnavailable) IsCode(code int) bool {
|
||||
return code == 503
|
||||
}
|
||||
|
||||
// Code gets the status code for the healthz service unavailable response
|
||||
func (o *HealthzServiceUnavailable) Code() int {
|
||||
return 503
|
||||
}
|
||||
|
||||
func (o *HealthzServiceUnavailable) Error() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /healthz][%d] healthzServiceUnavailable %s", 503, payload)
|
||||
return fmt.Sprintf("[GET /healthz][%d] healthzServiceUnavailable %+v", 503, o.Payload)
|
||||
}
|
||||
|
||||
func (o *HealthzServiceUnavailable) String() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /healthz][%d] healthzServiceUnavailable %s", 503, payload)
|
||||
}
|
||||
|
||||
func (o *HealthzServiceUnavailable) GetPayload() *models.HealthCheckResults {
|
||||
return o.Payload
|
||||
}
|
||||
@@ -172,7 +97,7 @@ func (o *HealthzServiceUnavailable) readResponse(response runtime.ClientResponse
|
||||
o.Payload = new(models.HealthCheckResults)
|
||||
|
||||
// response payload
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) {
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
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"
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
httptransport "github.com/go-openapi/runtime/client"
|
||||
"github.com/go-openapi/strfmt"
|
||||
)
|
||||
|
||||
@@ -15,31 +17,6 @@ func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientServi
|
||||
return &Client{transport: transport, formats: formats}
|
||||
}
|
||||
|
||||
// New creates a new operations API client with basic auth credentials.
|
||||
// It takes the following parameters:
|
||||
// - host: http host (github.com).
|
||||
// - basePath: any base path for the API client ("/v1", "/v3").
|
||||
// - scheme: http scheme ("http", "https").
|
||||
// - user: user for basic authentication header.
|
||||
// - password: password for basic authentication header.
|
||||
func NewClientWithBasicAuth(host, basePath, scheme, user, password string) ClientService {
|
||||
transport := httptransport.New(host, basePath, []string{scheme})
|
||||
transport.DefaultAuthentication = httptransport.BasicAuth(user, password)
|
||||
return &Client{transport: transport, formats: strfmt.Default}
|
||||
}
|
||||
|
||||
// New creates a new operations API client with a bearer token for authentication.
|
||||
// It takes the following parameters:
|
||||
// - host: http host (github.com).
|
||||
// - basePath: any base path for the API client ("/v1", "/v3").
|
||||
// - scheme: http scheme ("http", "https").
|
||||
// - bearerToken: bearer token for Bearer authentication header.
|
||||
func NewClientWithBearerToken(host, basePath, scheme, bearerToken string) ClientService {
|
||||
transport := httptransport.New(host, basePath, []string{scheme})
|
||||
transport.DefaultAuthentication = httptransport.BearerToken(bearerToken)
|
||||
return &Client{transport: transport, formats: strfmt.Default}
|
||||
}
|
||||
|
||||
/*
|
||||
Client for operations API
|
||||
*/
|
||||
@@ -48,7 +25,7 @@ type Client struct {
|
||||
formats strfmt.Registry
|
||||
}
|
||||
|
||||
// ClientOption may be used to customize the behavior of Client methods.
|
||||
// ClientOption is the option for Client methods
|
||||
type ClientOption func(*runtime.ClientOperation)
|
||||
|
||||
// ClientService is the interface for Client methods
|
||||
@@ -67,10 +44,10 @@ 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.
|
||||
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, opts ...ClientOption) (*CheckAllPodsOK, error) {
|
||||
// NOTE: parameters are not validated before sending
|
||||
// TODO: Validate the params before sending
|
||||
if params == nil {
|
||||
params = NewCheckAllPodsParams()
|
||||
}
|
||||
@@ -89,31 +66,26 @@ func (a *Client) CheckAllPods(params *CheckAllPodsParams, opts ...ClientOption)
|
||||
for _, opt := range opts {
|
||||
opt(op)
|
||||
}
|
||||
|
||||
result, err := a.transport.Submit(op)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// only one success response has to be checked
|
||||
success, ok := result.(*CheckAllPodsOK)
|
||||
if ok {
|
||||
return success, nil
|
||||
}
|
||||
|
||||
// unexpected success response.
|
||||
|
||||
// no default response is defined.
|
||||
//
|
||||
// safeguard: normally, in the absence of a default response, unknown success responses return an error above: so this is a codegen issue
|
||||
// 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 checkAllPods: API contract not enforced by server. Client expected to get an error, but got: %T", result)
|
||||
panic(msg)
|
||||
}
|
||||
|
||||
/*
|
||||
CheckServicePods Queries the API server for all other pods in this service, and pings them via their pods IPs. Calls their /ping endpoint
|
||||
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, opts ...ClientOption) (*CheckServicePodsOK, error) {
|
||||
// NOTE: parameters are not validated before sending
|
||||
// TODO: Validate the params before sending
|
||||
if params == nil {
|
||||
params = NewCheckServicePodsParams()
|
||||
}
|
||||
@@ -132,31 +104,26 @@ func (a *Client) CheckServicePods(params *CheckServicePodsParams, opts ...Client
|
||||
for _, opt := range opts {
|
||||
opt(op)
|
||||
}
|
||||
|
||||
result, err := a.transport.Submit(op)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// only one success response has to be checked
|
||||
success, ok := result.(*CheckServicePodsOK)
|
||||
if ok {
|
||||
return success, nil
|
||||
}
|
||||
|
||||
// unexpected success response.
|
||||
|
||||
// no default response is defined.
|
||||
//
|
||||
// safeguard: normally, in the absence of a default response, unknown success responses return an error above: so this is a codegen issue
|
||||
// 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 checkServicePods: API contract not enforced by server. Client expected to get an error, but got: %T", result)
|
||||
panic(msg)
|
||||
}
|
||||
|
||||
/*
|
||||
ClusterHealth Checks the full graph. Returns a binary OK or not OK.
|
||||
ClusterHealth Checks the full graph. Returns a binary OK or not OK.
|
||||
*/
|
||||
func (a *Client) ClusterHealth(params *ClusterHealthParams, opts ...ClientOption) (*ClusterHealthOK, error) {
|
||||
// NOTE: parameters are not validated before sending
|
||||
// TODO: Validate the params before sending
|
||||
if params == nil {
|
||||
params = NewClusterHealthParams()
|
||||
}
|
||||
@@ -175,31 +142,26 @@ func (a *Client) ClusterHealth(params *ClusterHealthParams, opts ...ClientOption
|
||||
for _, opt := range opts {
|
||||
opt(op)
|
||||
}
|
||||
|
||||
result, err := a.transport.Submit(op)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// only one success response has to be checked
|
||||
success, ok := result.(*ClusterHealthOK)
|
||||
if ok {
|
||||
return success, nil
|
||||
}
|
||||
|
||||
// unexpected success response.
|
||||
|
||||
// no default response is defined.
|
||||
//
|
||||
// safeguard: normally, in the absence of a default response, unknown success responses return an error above: so this is a codegen issue
|
||||
// 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.
|
||||
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, opts ...ClientOption) (*HealthzOK, error) {
|
||||
// NOTE: parameters are not validated before sending
|
||||
// TODO: Validate the params before sending
|
||||
if params == nil {
|
||||
params = NewHealthzParams()
|
||||
}
|
||||
@@ -218,31 +180,26 @@ func (a *Client) Healthz(params *HealthzParams, opts ...ClientOption) (*HealthzO
|
||||
for _, opt := range opts {
|
||||
opt(op)
|
||||
}
|
||||
|
||||
result, err := a.transport.Submit(op)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// only one success response has to be checked
|
||||
success, ok := result.(*HealthzOK)
|
||||
if ok {
|
||||
return success, nil
|
||||
}
|
||||
|
||||
// unexpected success response.
|
||||
|
||||
// no default response is defined.
|
||||
//
|
||||
// safeguard: normally, in the absence of a default response, unknown success responses return an error above: so this is a codegen issue
|
||||
// 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 healthz: API contract not enforced by server. Client expected to get an error, but got: %T", result)
|
||||
panic(msg)
|
||||
}
|
||||
|
||||
/*
|
||||
Ping return query stats
|
||||
Ping return query stats
|
||||
*/
|
||||
func (a *Client) Ping(params *PingParams, opts ...ClientOption) (*PingOK, error) {
|
||||
// NOTE: parameters are not validated before sending
|
||||
// TODO: Validate the params before sending
|
||||
if params == nil {
|
||||
params = NewPingParams()
|
||||
}
|
||||
@@ -261,22 +218,17 @@ func (a *Client) Ping(params *PingParams, opts ...ClientOption) (*PingOK, error)
|
||||
for _, opt := range opts {
|
||||
opt(op)
|
||||
}
|
||||
|
||||
result, err := a.transport.Submit(op)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// only one success response has to be checked
|
||||
success, ok := result.(*PingOK)
|
||||
if ok {
|
||||
return success, nil
|
||||
}
|
||||
|
||||
// unexpected success response.
|
||||
|
||||
// no default response is defined.
|
||||
//
|
||||
// safeguard: normally, in the absence of a default response, unknown success responses return an error above: so this is a codegen issue
|
||||
// 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 ping: API contract not enforced by server. Client expected to get an error, but got: %T", result)
|
||||
panic(msg)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
@@ -49,12 +52,10 @@ func NewPingParamsWithHTTPClient(client *http.Client) *PingParams {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
PingParams contains all the parameters to send to the API endpoint
|
||||
/* PingParams contains all the parameters to send to the API endpoint
|
||||
for the ping operation.
|
||||
|
||||
for the ping operation.
|
||||
|
||||
Typically these are written to a http.Request.
|
||||
Typically these are written to a http.Request.
|
||||
*/
|
||||
type PingParams struct {
|
||||
timeout time.Duration
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
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 (
|
||||
"encoding/json"
|
||||
stderrors "errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
@@ -20,7 +21,7 @@ type PingReader struct {
|
||||
}
|
||||
|
||||
// ReadResponse reads a server response into the received o.
|
||||
func (o *PingReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (any, error) {
|
||||
func (o *PingReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
|
||||
switch response.Code() {
|
||||
case 200:
|
||||
result := NewPingOK()
|
||||
@@ -29,7 +30,7 @@ func (o *PingReader) ReadResponse(response runtime.ClientResponse, consumer runt
|
||||
}
|
||||
return result, nil
|
||||
default:
|
||||
return nil, runtime.NewAPIError("[GET /ping] ping", 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())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,8 +39,7 @@ func NewPingOK() *PingOK {
|
||||
return &PingOK{}
|
||||
}
|
||||
|
||||
/*
|
||||
PingOK describes a response with status code 200, with default header values.
|
||||
/* PingOK describes a response with status code 200, with default header values.
|
||||
|
||||
return success
|
||||
*/
|
||||
@@ -47,46 +47,9 @@ type PingOK struct {
|
||||
Payload *models.PingResults
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this ping o k response has a 2xx status code
|
||||
func (o *PingOK) IsSuccess() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this ping o k response has a 3xx status code
|
||||
func (o *PingOK) IsRedirect() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsClientError returns true when this ping o k response has a 4xx status code
|
||||
func (o *PingOK) IsClientError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsServerError returns true when this ping o k response has a 5xx status code
|
||||
func (o *PingOK) IsServerError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCode returns true when this ping o k response a status code equal to that given
|
||||
func (o *PingOK) IsCode(code int) bool {
|
||||
return code == 200
|
||||
}
|
||||
|
||||
// Code gets the status code for the ping o k response
|
||||
func (o *PingOK) Code() int {
|
||||
return 200
|
||||
}
|
||||
|
||||
func (o *PingOK) Error() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /ping][%d] pingOK %s", 200, payload)
|
||||
return fmt.Sprintf("[GET /ping][%d] pingOK %+v", 200, o.Payload)
|
||||
}
|
||||
|
||||
func (o *PingOK) String() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /ping][%d] pingOK %s", 200, payload)
|
||||
}
|
||||
|
||||
func (o *PingOK) GetPayload() *models.PingResults {
|
||||
return o.Payload
|
||||
}
|
||||
@@ -96,7 +59,7 @@ func (o *PingOK) readResponse(response runtime.ClientResponse, consumer runtime.
|
||||
o.Payload = new(models.PingResults)
|
||||
|
||||
// response payload
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) {
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -44,13 +44,6 @@ var GoldpingerConfig = struct {
|
||||
|
||||
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:" "`
|
||||
|
||||
// UDP probe settings
|
||||
UDPEnabled bool `long:"udp-enabled" description:"Enable UDP probe for loss and hop metrics" env:"UDP_ENABLED"`
|
||||
UDPPort int `long:"udp-port" description:"Port for UDP echo listener" env:"UDP_PORT" default:"6969"`
|
||||
UDPPacketCount int `long:"udp-packet-count" description:"Number of UDP packets to send per probe" env:"UDP_PACKET_COUNT" default:"10"`
|
||||
UDPPacketSize int `long:"udp-packet-size" description:"Size of each UDP probe packet in bytes" env:"UDP_PACKET_SIZE" default:"64"`
|
||||
UDPTimeout time.Duration `long:"udp-timeout" description:"Timeout for UDP probe" env:"UDP_TIMEOUT" default:"1s"`
|
||||
|
||||
// Timeouts
|
||||
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"`
|
||||
|
||||
@@ -16,7 +16,6 @@ package goldpinger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
@@ -112,24 +111,6 @@ func (p *Pinger) Ping() {
|
||||
CountCall("made", "ping")
|
||||
start := time.Now()
|
||||
|
||||
// Run HTTP ping and UDP probe concurrently
|
||||
var udpResult UDPProbeResult
|
||||
var wg sync.WaitGroup
|
||||
if GoldpingerConfig.UDPEnabled {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
targetIP := pickPodHostIP(p.pod.PodIP, p.pod.HostIP)
|
||||
udpResult = ProbeUDP(
|
||||
targetIP,
|
||||
GoldpingerConfig.UDPPort,
|
||||
GoldpingerConfig.UDPPacketCount,
|
||||
GoldpingerConfig.UDPPacketSize,
|
||||
GoldpingerConfig.UDPTimeout,
|
||||
)
|
||||
}()
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), p.timeout)
|
||||
defer cancel()
|
||||
|
||||
@@ -139,34 +120,7 @@ func (p *Pinger) Ping() {
|
||||
responseTimeMs := responseTime.Nanoseconds() / int64(time.Millisecond)
|
||||
p.histogram.Observe(responseTime.Seconds())
|
||||
|
||||
// Wait for UDP probe to complete
|
||||
wg.Wait()
|
||||
|
||||
OK := (err == nil)
|
||||
|
||||
var lossPct float64
|
||||
var hopCount int32
|
||||
var udpRttMs float64
|
||||
if GoldpingerConfig.UDPEnabled {
|
||||
lossPct = udpResult.LossPct
|
||||
hopCount = udpResult.HopCount
|
||||
udpRttMs = udpResult.AvgRttS * 1000.0
|
||||
if udpResult.Err != nil {
|
||||
p.logger.Warn("UDP probe error", zap.Error(udpResult.Err))
|
||||
} else {
|
||||
p.logger.Debug("UDP probe complete",
|
||||
zap.Float64("lossPct", lossPct),
|
||||
zap.Int32("hopCount", hopCount),
|
||||
zap.Float64("udpRttMs", udpRttMs),
|
||||
)
|
||||
}
|
||||
SetPeerLossPct(p.pod.HostIP, p.pod.PodIP, lossPct)
|
||||
SetPeerHopCount(p.pod.HostIP, p.pod.PodIP, hopCount)
|
||||
if udpResult.AvgRttS > 0 {
|
||||
ObservePeerUDPRtt(p.pod.HostIP, p.pod.PodIP, udpResult.AvgRttS)
|
||||
}
|
||||
}
|
||||
|
||||
if OK {
|
||||
p.resultsChan <- PingAllPodsResult{
|
||||
podName: p.pod.Name,
|
||||
@@ -178,9 +132,6 @@ func (p *Pinger) Ping() {
|
||||
Response: resp.Payload,
|
||||
StatusCode: 200,
|
||||
ResponseTimeMs: responseTimeMs,
|
||||
LossPct: lossPct,
|
||||
HopCount: hopCount,
|
||||
UDPRttMs: udpRttMs,
|
||||
},
|
||||
}
|
||||
p.logger.Debug("Success pinging pod", zap.Duration("responseTime", responseTime))
|
||||
@@ -195,9 +146,6 @@ func (p *Pinger) Ping() {
|
||||
Error: err.Error(),
|
||||
StatusCode: 504,
|
||||
ResponseTimeMs: responseTimeMs,
|
||||
LossPct: lossPct,
|
||||
HopCount: hopCount,
|
||||
UDPRttMs: udpRttMs,
|
||||
},
|
||||
}
|
||||
p.logger.Warn("Ping returned error", zap.Duration("responseTime", responseTime), zap.Error(err))
|
||||
|
||||
@@ -123,50 +123,6 @@ var (
|
||||
"host",
|
||||
},
|
||||
)
|
||||
goldpingerPeersLossPct = prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "goldpinger_peers_loss_pct",
|
||||
Help: "UDP packet loss percentage to peer (0-100)",
|
||||
},
|
||||
[]string{
|
||||
"goldpinger_instance",
|
||||
"host_ip",
|
||||
"pod_ip",
|
||||
},
|
||||
)
|
||||
goldpingerPeersHopCount = prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "goldpinger_peers_hop_count",
|
||||
Help: "Estimated network hop count to peer from UDP TTL",
|
||||
},
|
||||
[]string{
|
||||
"goldpinger_instance",
|
||||
"host_ip",
|
||||
"pod_ip",
|
||||
},
|
||||
)
|
||||
goldpingerPeersUDPRtt = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "goldpinger_peers_udp_rtt_s",
|
||||
Help: "Histogram of UDP round-trip times to peers in seconds",
|
||||
Buckets: []float64{.0001, .00025, .0005, .001, .0025, .005, .01, .025, .05, .1, .25, .5, 1},
|
||||
},
|
||||
[]string{
|
||||
"goldpinger_instance",
|
||||
"host_ip",
|
||||
"pod_ip",
|
||||
},
|
||||
)
|
||||
goldpingerUDPErrorsCounter = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "goldpinger_udp_errors_total",
|
||||
Help: "Statistics of UDP probe errors per instance",
|
||||
},
|
||||
[]string{
|
||||
"goldpinger_instance",
|
||||
"host",
|
||||
},
|
||||
)
|
||||
bootTime = time.Now()
|
||||
)
|
||||
|
||||
@@ -180,10 +136,6 @@ func init() {
|
||||
prometheus.MustRegister(goldpingerDnsErrorsCounter)
|
||||
prometheus.MustRegister(goldPingerHttpErrorsCounter)
|
||||
prometheus.MustRegister(goldPingerTcpErrorsCounter)
|
||||
prometheus.MustRegister(goldpingerPeersLossPct)
|
||||
prometheus.MustRegister(goldpingerPeersHopCount)
|
||||
prometheus.MustRegister(goldpingerPeersUDPRtt)
|
||||
prometheus.MustRegister(goldpingerUDPErrorsCounter)
|
||||
zap.L().Info("Metrics setup - see /metrics")
|
||||
}
|
||||
|
||||
@@ -258,48 +210,6 @@ func CountHttpError(host string) {
|
||||
).Inc()
|
||||
}
|
||||
|
||||
// SetPeerLossPct sets the UDP packet loss percentage gauge for a peer
|
||||
func SetPeerLossPct(hostIP, podIP string, lossPct float64) {
|
||||
goldpingerPeersLossPct.WithLabelValues(
|
||||
GoldpingerConfig.Hostname,
|
||||
hostIP,
|
||||
podIP,
|
||||
).Set(lossPct)
|
||||
}
|
||||
|
||||
// SetPeerHopCount sets the estimated hop count gauge for a peer
|
||||
func SetPeerHopCount(hostIP, podIP string, hopCount int32) {
|
||||
goldpingerPeersHopCount.WithLabelValues(
|
||||
GoldpingerConfig.Hostname,
|
||||
hostIP,
|
||||
podIP,
|
||||
).Set(float64(hopCount))
|
||||
}
|
||||
|
||||
// DeletePeerUDPMetrics removes stale UDP metric labels for a destroyed peer
|
||||
func DeletePeerUDPMetrics(hostIP, podIP string) {
|
||||
goldpingerPeersLossPct.DeleteLabelValues(GoldpingerConfig.Hostname, hostIP, podIP)
|
||||
goldpingerPeersHopCount.DeleteLabelValues(GoldpingerConfig.Hostname, hostIP, podIP)
|
||||
goldpingerPeersUDPRtt.DeleteLabelValues(GoldpingerConfig.Hostname, hostIP, podIP)
|
||||
}
|
||||
|
||||
// ObservePeerUDPRtt records a UDP RTT observation in seconds
|
||||
func ObservePeerUDPRtt(hostIP, podIP string, rttS float64) {
|
||||
goldpingerPeersUDPRtt.WithLabelValues(
|
||||
GoldpingerConfig.Hostname,
|
||||
hostIP,
|
||||
podIP,
|
||||
).Observe(rttS)
|
||||
}
|
||||
|
||||
// CountUDPError counts instances of UDP probe errors
|
||||
func CountUDPError(host string) {
|
||||
goldpingerUDPErrorsCounter.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(
|
||||
|
||||
@@ -1,225 +0,0 @@
|
||||
// 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 (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/net/ipv4"
|
||||
"golang.org/x/net/ipv6"
|
||||
)
|
||||
|
||||
const (
|
||||
udpMagic = 0x47504E47 // "GPNG"
|
||||
udpHeaderSize = 16 // 4 magic + 4 seq + 8 timestamp
|
||||
|
||||
// udpMaxPacketSize is the maximum UDP packet we will read. Sized to the
|
||||
// standard Ethernet MTU (1500 bytes) which is the largest packet that
|
||||
// will survive most networks without fragmentation. Any configured
|
||||
// UDP_PACKET_SIZE larger than this will be clamped to this value to
|
||||
// avoid silent truncation on the receive side.
|
||||
udpMaxPacketSize = 1500
|
||||
)
|
||||
|
||||
// UDPProbeResult holds the results of a UDP probe to a peer
|
||||
type UDPProbeResult struct {
|
||||
LossPct float64
|
||||
HopCount int32
|
||||
AvgRttS float64
|
||||
Err error
|
||||
}
|
||||
|
||||
// StartUDPListener starts a UDP echo listener on the given port.
|
||||
// It echoes back any packet that starts with the GPNG magic number.
|
||||
func StartUDPListener(port int) {
|
||||
addr := net.JoinHostPort("::", strconv.Itoa(port))
|
||||
pc, err := net.ListenPacket("udp", addr)
|
||||
if err != nil {
|
||||
zap.L().Fatal("Failed to start UDP listener", zap.String("addr", addr), zap.Error(err))
|
||||
}
|
||||
defer pc.Close()
|
||||
|
||||
zap.L().Info("UDP echo listener started", zap.String("addr", addr))
|
||||
|
||||
buf := make([]byte, udpMaxPacketSize)
|
||||
for {
|
||||
n, remoteAddr, err := pc.ReadFrom(buf)
|
||||
if err != nil {
|
||||
zap.L().Warn("UDP read error", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
if n < udpHeaderSize {
|
||||
continue
|
||||
}
|
||||
magic := binary.BigEndian.Uint32(buf[0:4])
|
||||
if magic != udpMagic {
|
||||
continue
|
||||
}
|
||||
// Echo back the packet as-is
|
||||
_, err = pc.WriteTo(buf[:n], remoteAddr)
|
||||
if err != nil {
|
||||
zap.L().Warn("UDP write error", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ProbeUDP sends count UDP packets to the target and measures loss and hop count.
|
||||
func ProbeUDP(targetIP string, port, count, size int, timeout time.Duration) UDPProbeResult {
|
||||
if count <= 0 {
|
||||
return UDPProbeResult{Err: fmt.Errorf("packet count must be > 0, got %d", count)}
|
||||
}
|
||||
if size < udpHeaderSize {
|
||||
size = udpHeaderSize
|
||||
}
|
||||
if size > udpMaxPacketSize {
|
||||
size = udpMaxPacketSize
|
||||
}
|
||||
|
||||
addr := net.JoinHostPort(targetIP, strconv.Itoa(port))
|
||||
conn, err := net.Dial("udp", addr)
|
||||
if err != nil {
|
||||
CountUDPError(targetIP)
|
||||
return UDPProbeResult{LossPct: 100, Err: fmt.Errorf("dial: %w", err)}
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
// Determine if this is IPv4 or IPv6 and set up TTL/HopLimit reading
|
||||
isIPv6 := net.ParseIP(targetIP).To4() == nil
|
||||
var ttlValue int
|
||||
ttlFound := false
|
||||
|
||||
if isIPv6 {
|
||||
p := ipv6.NewPacketConn(conn.(*net.UDPConn))
|
||||
if err := p.SetControlMessage(ipv6.FlagHopLimit, true); err != nil {
|
||||
zap.L().Debug("Cannot set IPv6 hop limit flag", zap.Error(err))
|
||||
}
|
||||
} else {
|
||||
p := ipv4.NewPacketConn(conn.(*net.UDPConn))
|
||||
if err := p.SetControlMessage(ipv4.FlagTTL, true); err != nil {
|
||||
zap.L().Debug("Cannot set IPv4 TTL flag", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
// Build packet
|
||||
pkt := make([]byte, size)
|
||||
binary.BigEndian.PutUint32(pkt[0:4], udpMagic)
|
||||
|
||||
// Send all packets
|
||||
for i := 0; i < count; i++ {
|
||||
binary.BigEndian.PutUint32(pkt[4:8], uint32(i))
|
||||
binary.BigEndian.PutUint64(pkt[8:16], uint64(time.Now().UnixNano()))
|
||||
_, err := conn.Write(pkt)
|
||||
if err != nil {
|
||||
CountUDPError(targetIP)
|
||||
zap.L().Debug("UDP send error", zap.Int("seq", i), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
// Receive replies
|
||||
received := 0
|
||||
var totalRttNs int64
|
||||
deadline := time.Now().Add(timeout)
|
||||
conn.SetReadDeadline(deadline)
|
||||
|
||||
recvBuf := make([]byte, udpMaxPacketSize)
|
||||
|
||||
if isIPv6 {
|
||||
p := ipv6.NewPacketConn(conn.(*net.UDPConn))
|
||||
for received < count {
|
||||
n, cm, _, err := p.ReadFrom(recvBuf)
|
||||
now := time.Now()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
if n < udpHeaderSize {
|
||||
continue
|
||||
}
|
||||
magic := binary.BigEndian.Uint32(recvBuf[0:4])
|
||||
if magic != udpMagic {
|
||||
continue
|
||||
}
|
||||
sentNs := int64(binary.BigEndian.Uint64(recvBuf[8:16]))
|
||||
totalRttNs += now.UnixNano() - sentNs
|
||||
received++
|
||||
if cm != nil && cm.HopLimit > 0 && !ttlFound {
|
||||
ttlValue = cm.HopLimit
|
||||
ttlFound = true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p := ipv4.NewPacketConn(conn.(*net.UDPConn))
|
||||
for received < count {
|
||||
n, cm, _, err := p.ReadFrom(recvBuf)
|
||||
now := time.Now()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
if n < udpHeaderSize {
|
||||
continue
|
||||
}
|
||||
magic := binary.BigEndian.Uint32(recvBuf[0:4])
|
||||
if magic != udpMagic {
|
||||
continue
|
||||
}
|
||||
sentNs := int64(binary.BigEndian.Uint64(recvBuf[8:16]))
|
||||
totalRttNs += now.UnixNano() - sentNs
|
||||
received++
|
||||
if cm != nil && cm.TTL > 0 && !ttlFound {
|
||||
ttlValue = cm.TTL
|
||||
ttlFound = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lossPct := float64(count-received) / float64(count) * 100.0
|
||||
|
||||
var hopCount int32
|
||||
if ttlFound {
|
||||
hopCount = estimateHops(ttlValue)
|
||||
}
|
||||
|
||||
var avgRttS float64
|
||||
if received > 0 {
|
||||
avgRttS = float64(totalRttNs) / float64(received) / 1e9
|
||||
}
|
||||
|
||||
return UDPProbeResult{
|
||||
LossPct: lossPct,
|
||||
HopCount: hopCount,
|
||||
AvgRttS: avgRttS,
|
||||
}
|
||||
}
|
||||
|
||||
// estimateHops estimates the number of hops from the received TTL.
|
||||
// Common initial TTL values are 64 (Linux) and 128 (Windows).
|
||||
func estimateHops(receivedTTL int) int32 {
|
||||
if receivedTTL <= 0 {
|
||||
return 0
|
||||
}
|
||||
initialTTL := 64
|
||||
if receivedTTL > 64 {
|
||||
initialTTL = 128
|
||||
}
|
||||
hops := initialTTL - receivedTTL
|
||||
if hops < 0 {
|
||||
hops = 0
|
||||
}
|
||||
return int32(hops)
|
||||
}
|
||||
@@ -1,180 +0,0 @@
|
||||
package goldpinger
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"net"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func startTestEchoListener(t *testing.T) (int, func()) {
|
||||
t.Helper()
|
||||
pc, err := net.ListenPacket("udp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
port := pc.LocalAddr().(*net.UDPAddr).Port
|
||||
|
||||
go func() {
|
||||
buf := make([]byte, udpMaxPacketSize)
|
||||
for {
|
||||
n, addr, err := pc.ReadFrom(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if n >= udpHeaderSize {
|
||||
magic := binary.BigEndian.Uint32(buf[0:4])
|
||||
if magic == udpMagic {
|
||||
pc.WriteTo(buf[:n], addr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return port, func() { pc.Close() }
|
||||
}
|
||||
|
||||
// startLossyEchoListener echoes back packets but drops every dropEveryN-th
|
||||
// packet (1-indexed). For example, dropEveryN=3 drops packets 3, 6, 9, etc.
|
||||
func startLossyEchoListener(t *testing.T, dropEveryN int) (int, func()) {
|
||||
t.Helper()
|
||||
pc, err := net.ListenPacket("udp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
port := pc.LocalAddr().(*net.UDPAddr).Port
|
||||
|
||||
var counter atomic.Int64
|
||||
|
||||
go func() {
|
||||
buf := make([]byte, udpMaxPacketSize)
|
||||
for {
|
||||
n, addr, err := pc.ReadFrom(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if n >= udpHeaderSize {
|
||||
magic := binary.BigEndian.Uint32(buf[0:4])
|
||||
if magic == udpMagic {
|
||||
seq := counter.Add(1)
|
||||
if seq%int64(dropEveryN) == 0 {
|
||||
// Drop this packet — don't echo
|
||||
continue
|
||||
}
|
||||
pc.WriteTo(buf[:n], addr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return port, func() { pc.Close() }
|
||||
}
|
||||
|
||||
func TestProbeUDP_NoLoss(t *testing.T) {
|
||||
port, cleanup := startTestEchoListener(t)
|
||||
defer cleanup()
|
||||
|
||||
result := ProbeUDP("127.0.0.1", port, 10, 64, 2*time.Second)
|
||||
if result.Err != nil {
|
||||
t.Fatalf("unexpected error: %v", result.Err)
|
||||
}
|
||||
if result.LossPct != 0 {
|
||||
t.Errorf("expected 0%% loss, got %.1f%%", result.LossPct)
|
||||
}
|
||||
if result.AvgRttS <= 0 {
|
||||
t.Errorf("expected positive RTT, got %.6f s", result.AvgRttS)
|
||||
}
|
||||
t.Logf("avg UDP RTT: %.4f ms", result.AvgRttS*1000)
|
||||
}
|
||||
|
||||
func TestProbeUDP_FullLoss(t *testing.T) {
|
||||
// Bind a port then close it so nothing is listening.
|
||||
// This avoids assuming a hardcoded port like 19999 is free.
|
||||
pc, err := net.ListenPacket("udp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
port := pc.LocalAddr().(*net.UDPAddr).Port
|
||||
pc.Close()
|
||||
|
||||
result := ProbeUDP("127.0.0.1", port, 5, 64, 200*time.Millisecond)
|
||||
if result.LossPct != 100 {
|
||||
t.Errorf("expected 100%% loss, got %.1f%%", result.LossPct)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProbeUDP_PartialLoss(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
count int
|
||||
dropEveryN int
|
||||
expectedPct float64
|
||||
}{
|
||||
{"drop every 2nd (50%)", 10, 2, 50.0},
|
||||
{"drop every 3rd (33.3%)", 9, 3, 100.0 / 3.0},
|
||||
{"drop every 5th (20%)", 10, 5, 20.0},
|
||||
{"drop every 10th (10%)", 10, 10, 10.0},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
port, cleanup := startLossyEchoListener(t, tt.dropEveryN)
|
||||
defer cleanup()
|
||||
|
||||
result := ProbeUDP("127.0.0.1", port, tt.count, 64, 2*time.Second)
|
||||
if result.Err != nil {
|
||||
t.Fatalf("unexpected error: %v", result.Err)
|
||||
}
|
||||
// Allow small floating point tolerance
|
||||
diff := result.LossPct - tt.expectedPct
|
||||
if diff < -0.1 || diff > 0.1 {
|
||||
t.Errorf("expected %.1f%% loss, got %.1f%%", tt.expectedPct, result.LossPct)
|
||||
}
|
||||
t.Logf("loss: %.1f%% (expected %.1f%%)", result.LossPct, tt.expectedPct)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProbeUDP_ZeroCount(t *testing.T) {
|
||||
result := ProbeUDP("127.0.0.1", 12345, 0, 64, 200*time.Millisecond)
|
||||
if result.Err == nil {
|
||||
t.Error("expected error for count=0, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProbeUDP_PacketFormat(t *testing.T) {
|
||||
pkt := make([]byte, 64)
|
||||
binary.BigEndian.PutUint32(pkt[0:4], udpMagic)
|
||||
binary.BigEndian.PutUint32(pkt[4:8], 42)
|
||||
binary.BigEndian.PutUint64(pkt[8:16], uint64(time.Now().UnixNano()))
|
||||
|
||||
magic := binary.BigEndian.Uint32(pkt[0:4])
|
||||
if magic != 0x47504E47 {
|
||||
t.Errorf("expected magic 0x47504E47, got 0x%X", magic)
|
||||
}
|
||||
seq := binary.BigEndian.Uint32(pkt[4:8])
|
||||
if seq != 42 {
|
||||
t.Errorf("expected seq 42, got %d", seq)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEstimateHops(t *testing.T) {
|
||||
tests := []struct {
|
||||
ttl int
|
||||
want int32
|
||||
}{
|
||||
{64, 0}, // same host, Linux
|
||||
{63, 1}, // 1 hop, Linux
|
||||
{56, 8}, // 8 hops, Linux
|
||||
{128, 0}, // same host, Windows (TTL > 64 → initial=128)
|
||||
{127, 1}, // 1 hop, Windows
|
||||
{0, 0}, // invalid
|
||||
}
|
||||
for _, tt := range tests {
|
||||
got := estimateHops(tt.ttl)
|
||||
if got != tt.want {
|
||||
t.Errorf("estimateHops(%d) = %d, want %d", tt.ttl, got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,11 +93,10 @@ func updatePingers(resultsChan chan<- PingAllPodsResult) {
|
||||
|
||||
// createPingers allocates a new pinger object for each new goldpinger Pod that's been discovered
|
||||
// It also:
|
||||
//
|
||||
// (a) initializes a result object in checkResults to store info on that pod
|
||||
// (b) starts a new goroutines to continuously ping the given pod.
|
||||
// Each new goroutine waits for a given time before starting the continuous ping
|
||||
// to prevent a thundering herd
|
||||
// (a) initializes a result object in checkResults to store info on that pod
|
||||
// (b) starts a new goroutines to continuously ping the given pod.
|
||||
// Each new goroutine waits for a given time before starting the continuous ping
|
||||
// to prevent a thundering herd
|
||||
func createPingers(pingers map[string]*Pinger, newPods map[string]*GoldpingerPod, resultsChan chan<- PingAllPodsResult, refreshPeriod time.Duration) {
|
||||
if len(newPods) == 0 {
|
||||
// I have nothing to do
|
||||
@@ -137,11 +136,6 @@ func destroyPingers(pingers map[string]*Pinger, deletedPods map[string]*Goldping
|
||||
// Close the channel to stop pinging
|
||||
close(pinger.stopChan)
|
||||
|
||||
// Clean up stale UDP metric labels for this peer
|
||||
if GoldpingerConfig.UDPEnabled {
|
||||
DeletePeerUDPMetrics(pod.HostIP, pod.PodIP)
|
||||
}
|
||||
|
||||
// delete from pingers
|
||||
delete(pingers, podName)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
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"
|
||||
stderrors "errors"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
@@ -91,15 +93,11 @@ func (m *CheckAllPodResult) validateResponse(formats strfmt.Registry) error {
|
||||
|
||||
if m.Response != nil {
|
||||
if err := m.Response.Validate(formats); err != nil {
|
||||
ve := new(errors.Validation)
|
||||
if stderrors.As(err, &ve) {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("response")
|
||||
}
|
||||
ce := new(errors.CompositeError)
|
||||
if stderrors.As(err, &ce) {
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("response")
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -124,21 +122,12 @@ func (m *CheckAllPodResult) ContextValidate(ctx context.Context, formats strfmt.
|
||||
func (m *CheckAllPodResult) contextValidateResponse(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Response != nil {
|
||||
|
||||
if swag.IsZero(m.Response) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.Response.ContextValidate(ctx, formats); err != nil {
|
||||
ve := new(errors.Validation)
|
||||
if stderrors.As(err, &ve) {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("response")
|
||||
}
|
||||
ce := new(errors.CompositeError)
|
||||
if stderrors.As(err, &ce) {
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("response")
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
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"
|
||||
stderrors "errors"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
@@ -71,15 +73,11 @@ func (m *CheckAllResults) validateHosts(formats strfmt.Registry) error {
|
||||
|
||||
if m.Hosts[i] != nil {
|
||||
if err := m.Hosts[i].Validate(formats); err != nil {
|
||||
ve := new(errors.Validation)
|
||||
if stderrors.As(err, &ve) {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("hosts" + "." + strconv.Itoa(i))
|
||||
}
|
||||
ce := new(errors.CompositeError)
|
||||
if stderrors.As(err, &ce) {
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("hosts" + "." + strconv.Itoa(i))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -119,15 +117,11 @@ func (m *CheckAllResults) validateResponses(formats strfmt.Registry) error {
|
||||
}
|
||||
if val, ok := m.Responses[k]; ok {
|
||||
if err := val.Validate(formats); err != nil {
|
||||
ve := new(errors.Validation)
|
||||
if stderrors.As(err, &ve) {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("responses" + "." + k)
|
||||
}
|
||||
ce := new(errors.CompositeError)
|
||||
if stderrors.As(err, &ce) {
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("responses" + "." + k)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -164,21 +158,12 @@ func (m *CheckAllResults) contextValidateHosts(ctx context.Context, formats strf
|
||||
for i := 0; i < len(m.Hosts); i++ {
|
||||
|
||||
if m.Hosts[i] != nil {
|
||||
|
||||
if swag.IsZero(m.Hosts[i]) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.Hosts[i].ContextValidate(ctx, formats); err != nil {
|
||||
ve := new(errors.Validation)
|
||||
if stderrors.As(err, &ve) {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("hosts" + "." + strconv.Itoa(i))
|
||||
}
|
||||
ce := new(errors.CompositeError)
|
||||
if stderrors.As(err, &ce) {
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("hosts" + "." + strconv.Itoa(i))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
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"
|
||||
stderrors "errors"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
@@ -54,15 +56,11 @@ func (m *CheckResults) validatePodResults(formats strfmt.Registry) error {
|
||||
}
|
||||
if val, ok := m.PodResults[k]; ok {
|
||||
if err := val.Validate(formats); err != nil {
|
||||
ve := new(errors.Validation)
|
||||
if stderrors.As(err, &ve) {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("podResults" + "." + k)
|
||||
}
|
||||
ce := new(errors.CompositeError)
|
||||
if stderrors.As(err, &ce) {
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("podResults" + "." + k)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -79,15 +77,11 @@ func (m *CheckResults) validateProbeResults(formats strfmt.Registry) error {
|
||||
|
||||
if m.ProbeResults != nil {
|
||||
if err := m.ProbeResults.Validate(formats); err != nil {
|
||||
ve := new(errors.Validation)
|
||||
if stderrors.As(err, &ve) {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("probeResults")
|
||||
}
|
||||
ce := new(errors.CompositeError)
|
||||
if stderrors.As(err, &ce) {
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("probeResults")
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -130,20 +124,12 @@ func (m *CheckResults) contextValidatePodResults(ctx context.Context, formats st
|
||||
|
||||
func (m *CheckResults) contextValidateProbeResults(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if swag.IsZero(m.ProbeResults) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.ProbeResults.ContextValidate(ctx, formats); err != nil {
|
||||
ve := new(errors.Validation)
|
||||
if stderrors.As(err, &ve) {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("probeResults")
|
||||
}
|
||||
ce := new(errors.CompositeError)
|
||||
if stderrors.As(err, &ce) {
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("probeResults")
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -57,7 +60,7 @@ func (m *ClusterHealthResults) Validate(formats strfmt.Registry) error {
|
||||
|
||||
func (m *ClusterHealthResults) validateOK(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("OK", "body", m.OK); err != nil {
|
||||
if err := validate.Required("OK", "body", bool(m.OK)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
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"
|
||||
stderrors "errors"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
@@ -62,15 +64,11 @@ func (m *PingResults) validateReceived(formats strfmt.Registry) error {
|
||||
|
||||
if m.Received != nil {
|
||||
if err := m.Received.Validate(formats); err != nil {
|
||||
ve := new(errors.Validation)
|
||||
if stderrors.As(err, &ve) {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("received")
|
||||
}
|
||||
ce := new(errors.CompositeError)
|
||||
if stderrors.As(err, &ce) {
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("received")
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -95,21 +93,12 @@ func (m *PingResults) ContextValidate(ctx context.Context, formats strfmt.Regist
|
||||
func (m *PingResults) contextValidateReceived(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Received != nil {
|
||||
|
||||
if swag.IsZero(m.Received) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.Received.ContextValidate(ctx, formats); err != nil {
|
||||
ve := new(errors.Validation)
|
||||
if stderrors.As(err, &ve) {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("received")
|
||||
}
|
||||
ce := new(errors.CompositeError)
|
||||
if stderrors.As(err, &ce) {
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("received")
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
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"
|
||||
stderrors "errors"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
@@ -35,12 +37,6 @@ type PodResult struct {
|
||||
// error
|
||||
Error string `json:"error,omitempty"`
|
||||
|
||||
// estimated network hop count from UDP TTL
|
||||
HopCount int32 `json:"hop-count,omitempty"`
|
||||
|
||||
// UDP packet loss percentage (0-100)
|
||||
LossPct float64 `json:"loss-pct,omitempty"`
|
||||
|
||||
// response
|
||||
Response *PingResults `json:"response,omitempty"`
|
||||
|
||||
@@ -49,9 +45,6 @@ type PodResult struct {
|
||||
|
||||
// status code
|
||||
StatusCode int32 `json:"status-code,omitempty"`
|
||||
|
||||
// average UDP round-trip time in milliseconds
|
||||
UDPRttMs float64 `json:"udp-rtt-ms,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this pod result
|
||||
@@ -123,15 +116,11 @@ func (m *PodResult) validateResponse(formats strfmt.Registry) error {
|
||||
|
||||
if m.Response != nil {
|
||||
if err := m.Response.Validate(formats); err != nil {
|
||||
ve := new(errors.Validation)
|
||||
if stderrors.As(err, &ve) {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("response")
|
||||
}
|
||||
ce := new(errors.CompositeError)
|
||||
if stderrors.As(err, &ce) {
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("response")
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -156,21 +145,12 @@ func (m *PodResult) ContextValidate(ctx context.Context, formats strfmt.Registry
|
||||
func (m *PodResult) contextValidateResponse(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Response != nil {
|
||||
|
||||
if swag.IsZero(m.Response) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.Response.ContextValidate(ctx, formats); err != nil {
|
||||
ve := new(errors.Validation)
|
||||
if stderrors.As(err, &ve) {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("response")
|
||||
}
|
||||
ce := new(errors.CompositeError)
|
||||
if stderrors.As(err, &ce) {
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("response")
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
|
||||
@@ -2,14 +2,15 @@
|
||||
|
||||
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"
|
||||
stderrors "errors"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
@@ -31,15 +32,11 @@ func (m ProbeResults) Validate(formats strfmt.Registry) error {
|
||||
for i := 0; i < len(m[k]); i++ {
|
||||
|
||||
if err := m[k][i].Validate(formats); err != nil {
|
||||
ve := new(errors.Validation)
|
||||
if stderrors.As(err, &ve) {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName(k + "." + strconv.Itoa(i))
|
||||
}
|
||||
ce := new(errors.CompositeError)
|
||||
if stderrors.As(err, &ce) {
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName(k + "." + strconv.Itoa(i))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -61,20 +58,12 @@ func (m ProbeResults) ContextValidate(ctx context.Context, formats strfmt.Regist
|
||||
|
||||
for i := 0; i < len(m[k]); i++ {
|
||||
|
||||
if swag.IsZero(m[k][i]) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m[k][i].ContextValidate(ctx, formats); err != nil {
|
||||
ve := new(errors.Validation)
|
||||
if stderrors.As(err, &ve) {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName(k + "." + strconv.Itoa(i))
|
||||
}
|
||||
ce := new(errors.CompositeError)
|
||||
if stderrors.As(err, &ce) {
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName(k + "." + strconv.Itoa(i))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
|
||||
// Package restapi Goldpinger
|
||||
//
|
||||
// Schemes:
|
||||
// http
|
||||
// Host: localhost
|
||||
// BasePath: /
|
||||
// Version: 3.0.0
|
||||
// Schemes:
|
||||
// http
|
||||
// Host: localhost
|
||||
// BasePath: /
|
||||
// Version: 3.0.0
|
||||
//
|
||||
// Consumes:
|
||||
// - application/json
|
||||
// Consumes:
|
||||
// - application/json
|
||||
//
|
||||
// Produces:
|
||||
// - application/json
|
||||
// Produces:
|
||||
// - application/json
|
||||
//
|
||||
// swagger:meta
|
||||
package restapi
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
package restapi
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
@@ -167,6 +170,12 @@ func init() {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"dnsResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/DnsResults"
|
||||
}
|
||||
},
|
||||
"hosts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -194,10 +203,10 @@ func init() {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"probeResults": {
|
||||
"httpResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/ProbeResults"
|
||||
"$ref": "#/definitions/HttpResults"
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
@@ -205,20 +214,32 @@ func init() {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/CheckAllPodResult"
|
||||
}
|
||||
},
|
||||
"tcpResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/TcpResults"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"CheckResults": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"dnsResults": {
|
||||
"$ref": "#/definitions/DnsResults"
|
||||
},
|
||||
"httpResults": {
|
||||
"$ref": "#/definitions/HttpResults"
|
||||
},
|
||||
"podResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/PodResult"
|
||||
}
|
||||
},
|
||||
"probeResults": {
|
||||
"$ref": "#/definitions/ProbeResults"
|
||||
"tcpResults": {
|
||||
"$ref": "#/definitions/TcpResults"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -258,6 +279,12 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"DnsResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/ProbeResult"
|
||||
}
|
||||
},
|
||||
"HealthCheckResults": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -275,6 +302,12 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"HttpResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/ProbeResult"
|
||||
}
|
||||
},
|
||||
"PingResults": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -309,16 +342,6 @@ func init() {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"hop-count": {
|
||||
"description": "estimated network hop count from UDP TTL",
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"loss-pct": {
|
||||
"description": "UDP packet loss percentage (0-100)",
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"response": {
|
||||
"$ref": "#/definitions/PingResults"
|
||||
},
|
||||
@@ -330,11 +353,6 @@ func init() {
|
||||
"status-code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"udp-rtt-ms": {
|
||||
"description": "average UDP round-trip time in milliseconds",
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -343,22 +361,16 @@ func init() {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"protocol": {
|
||||
"type": "string"
|
||||
},
|
||||
"response-time-ms": {
|
||||
"type": "number",
|
||||
"format": "int64"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ProbeResults": {
|
||||
"TcpResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/ProbeResult"
|
||||
}
|
||||
"$ref": "#/definitions/ProbeResult"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -516,6 +528,12 @@ func init() {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"dnsResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/DnsResults"
|
||||
}
|
||||
},
|
||||
"hosts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -530,10 +548,10 @@ func init() {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"probeResults": {
|
||||
"httpResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/ProbeResults"
|
||||
"$ref": "#/definitions/HttpResults"
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
@@ -541,6 +559,12 @@ func init() {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/CheckAllPodResult"
|
||||
}
|
||||
},
|
||||
"tcpResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/TcpResults"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -563,14 +587,20 @@ func init() {
|
||||
"CheckResults": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"dnsResults": {
|
||||
"$ref": "#/definitions/DnsResults"
|
||||
},
|
||||
"httpResults": {
|
||||
"$ref": "#/definitions/HttpResults"
|
||||
},
|
||||
"podResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/PodResult"
|
||||
}
|
||||
},
|
||||
"probeResults": {
|
||||
"$ref": "#/definitions/ProbeResults"
|
||||
"tcpResults": {
|
||||
"$ref": "#/definitions/TcpResults"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -610,6 +640,12 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"DnsResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/ProbeResult"
|
||||
}
|
||||
},
|
||||
"HealthCheckResults": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -627,6 +663,12 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"HttpResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/ProbeResult"
|
||||
}
|
||||
},
|
||||
"PingResults": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -661,16 +703,6 @@ func init() {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"hop-count": {
|
||||
"description": "estimated network hop count from UDP TTL",
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"loss-pct": {
|
||||
"description": "UDP packet loss percentage (0-100)",
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"response": {
|
||||
"$ref": "#/definitions/PingResults"
|
||||
},
|
||||
@@ -682,11 +714,6 @@ func init() {
|
||||
"status-code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"udp-rtt-ms": {
|
||||
"description": "average UDP round-trip time in milliseconds",
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -695,22 +722,16 @@ func init() {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"protocol": {
|
||||
"type": "string"
|
||||
},
|
||||
"response-time-ms": {
|
||||
"type": "number",
|
||||
"format": "int64"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ProbeResults": {
|
||||
"TcpResults": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/ProbeResult"
|
||||
}
|
||||
"$ref": "#/definitions/ProbeResult"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -26,10 +29,10 @@ 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.
|
||||
|
||||
*/
|
||||
type CheckAllPods struct {
|
||||
Context *middleware.Context
|
||||
@@ -48,7 +51,6 @@ func (o *CheckAllPods) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
res := o.Handler.Handle(Params) // actually handle the request
|
||||
|
||||
o.Context.Respond(rw, r, route.Produces, route, res)
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -22,6 +25,7 @@ func NewCheckAllPodsParams() CheckAllPodsParams {
|
||||
//
|
||||
// swagger:parameters checkAllPods
|
||||
type CheckAllPodsParams struct {
|
||||
|
||||
// HTTP Request Object
|
||||
HTTPRequest *http.Request `json:"-"`
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -13,8 +16,7 @@ import (
|
||||
// CheckAllPodsOKCode is the HTTP code returned for type CheckAllPodsOK
|
||||
const CheckAllPodsOKCode int = 200
|
||||
|
||||
/*
|
||||
CheckAllPodsOK Success, return response
|
||||
/*CheckAllPodsOK Success, return response
|
||||
|
||||
swagger:response checkAllPodsOK
|
||||
*/
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -26,10 +29,10 @@ 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
|
||||
|
||||
*/
|
||||
type CheckServicePods struct {
|
||||
Context *middleware.Context
|
||||
@@ -48,7 +51,6 @@ func (o *CheckServicePods) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
res := o.Handler.Handle(Params) // actually handle the request
|
||||
|
||||
o.Context.Respond(rw, r, route.Produces, route, res)
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -22,6 +25,7 @@ func NewCheckServicePodsParams() CheckServicePodsParams {
|
||||
//
|
||||
// swagger:parameters checkServicePods
|
||||
type CheckServicePodsParams struct {
|
||||
|
||||
// HTTP Request Object
|
||||
HTTPRequest *http.Request `json:"-"`
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -13,8 +16,7 @@ import (
|
||||
// CheckServicePodsOKCode is the HTTP code returned for type CheckServicePodsOK
|
||||
const CheckServicePodsOKCode int = 200
|
||||
|
||||
/*
|
||||
CheckServicePodsOK Success, return response
|
||||
/*CheckServicePodsOK Success, return response
|
||||
|
||||
swagger:response checkServicePodsOK
|
||||
*/
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -26,10 +29,10 @@ func NewClusterHealth(ctx *middleware.Context, handler ClusterHealthHandler) *Cl
|
||||
return &ClusterHealth{Context: ctx, Handler: handler}
|
||||
}
|
||||
|
||||
/*
|
||||
ClusterHealth swagger:route GET /cluster_health clusterHealth
|
||||
/* ClusterHealth swagger:route GET /cluster_health clusterHealth
|
||||
|
||||
Checks the full graph. Returns a binary OK or not OK.
|
||||
|
||||
*/
|
||||
type ClusterHealth struct {
|
||||
Context *middleware.Context
|
||||
@@ -48,7 +51,6 @@ func (o *ClusterHealth) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
res := o.Handler.Handle(Params) // actually handle the request
|
||||
|
||||
o.Context.Respond(rw, r, route.Produces, route, res)
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -22,6 +25,7 @@ func NewClusterHealthParams() ClusterHealthParams {
|
||||
//
|
||||
// swagger:parameters clusterHealth
|
||||
type ClusterHealthParams struct {
|
||||
|
||||
// HTTP Request Object
|
||||
HTTPRequest *http.Request `json:"-"`
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -13,8 +16,7 @@ import (
|
||||
// ClusterHealthOKCode is the HTTP code returned for type ClusterHealthOK
|
||||
const ClusterHealthOKCode int = 200
|
||||
|
||||
/*
|
||||
ClusterHealthOK Healthy cluster
|
||||
/*ClusterHealthOK Healthy cluster
|
||||
|
||||
swagger:response clusterHealthOK
|
||||
*/
|
||||
@@ -58,8 +60,7 @@ func (o *ClusterHealthOK) WriteResponse(rw http.ResponseWriter, producer runtime
|
||||
// ClusterHealthIMATeapotCode is the HTTP code returned for type ClusterHealthIMATeapot
|
||||
const ClusterHealthIMATeapotCode int = 418
|
||||
|
||||
/*
|
||||
ClusterHealthIMATeapot Unhealthy cluster
|
||||
/*ClusterHealthIMATeapot Unhealthy cluster
|
||||
|
||||
swagger:response clusterHealthIMATeapot
|
||||
*/
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
"net/http"
|
||||
@@ -40,32 +43,18 @@ func NewGoldpingerAPI(spec *loads.Document) *GoldpingerAPI {
|
||||
JSONProducer: runtime.JSONProducer(),
|
||||
|
||||
CheckAllPodsHandler: CheckAllPodsHandlerFunc(func(params CheckAllPodsParams) middleware.Responder {
|
||||
_ = params
|
||||
|
||||
return middleware.NotImplemented("operation CheckAllPods has not yet been implemented")
|
||||
}),
|
||||
|
||||
CheckServicePodsHandler: CheckServicePodsHandlerFunc(func(params CheckServicePodsParams) middleware.Responder {
|
||||
_ = params
|
||||
|
||||
return middleware.NotImplemented("operation CheckServicePods has not yet been implemented")
|
||||
}),
|
||||
|
||||
ClusterHealthHandler: ClusterHealthHandlerFunc(func(params ClusterHealthParams) middleware.Responder {
|
||||
_ = params
|
||||
|
||||
return middleware.NotImplemented("operation ClusterHealth has not yet been implemented")
|
||||
}),
|
||||
|
||||
HealthzHandler: HealthzHandlerFunc(func(params HealthzParams) middleware.Responder {
|
||||
_ = params
|
||||
|
||||
return middleware.NotImplemented("operation Healthz has not yet been implemented")
|
||||
}),
|
||||
|
||||
PingHandler: PingHandlerFunc(func(params PingParams) middleware.Responder {
|
||||
_ = params
|
||||
|
||||
return middleware.NotImplemented("operation Ping has not yet been implemented")
|
||||
}),
|
||||
}
|
||||
@@ -131,7 +120,7 @@ type GoldpingerAPI struct {
|
||||
CommandLineOptionsGroups []swag.CommandLineOptionsGroup
|
||||
|
||||
// User defined logger function.
|
||||
Logger func(string, ...any)
|
||||
Logger func(string, ...interface{})
|
||||
}
|
||||
|
||||
// UseRedoc for documentation at /docs
|
||||
@@ -230,12 +219,12 @@ func (o *GoldpingerAPI) Authorizer() runtime.Authorizer {
|
||||
}
|
||||
|
||||
// ConsumersFor gets the consumers for the specified media types.
|
||||
//
|
||||
// MIME type parameters are ignored here.
|
||||
func (o *GoldpingerAPI) ConsumersFor(mediaTypes []string) map[string]runtime.Consumer {
|
||||
result := make(map[string]runtime.Consumer, len(mediaTypes))
|
||||
for _, mt := range mediaTypes {
|
||||
if mt == "application/json" {
|
||||
switch mt {
|
||||
case "application/json":
|
||||
result["application/json"] = o.JSONConsumer
|
||||
}
|
||||
|
||||
@@ -243,17 +232,16 @@ func (o *GoldpingerAPI) ConsumersFor(mediaTypes []string) map[string]runtime.Con
|
||||
result[mt] = c
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// ProducersFor gets the producers for the specified media types.
|
||||
//
|
||||
// MIME type parameters are ignored here.
|
||||
func (o *GoldpingerAPI) ProducersFor(mediaTypes []string) map[string]runtime.Producer {
|
||||
result := make(map[string]runtime.Producer, len(mediaTypes))
|
||||
for _, mt := range mediaTypes {
|
||||
if mt == "application/json" {
|
||||
switch mt {
|
||||
case "application/json":
|
||||
result["application/json"] = o.JSONProducer
|
||||
}
|
||||
|
||||
@@ -261,7 +249,6 @@ func (o *GoldpingerAPI) ProducersFor(mediaTypes []string) map[string]runtime.Pro
|
||||
result[mt] = p
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -357,6 +344,6 @@ func (o *GoldpingerAPI) AddMiddlewareFor(method, path string, builder middleware
|
||||
}
|
||||
o.Init()
|
||||
if h, ok := o.handlers[um][path]; ok {
|
||||
o.handlers[um][path] = builder(h)
|
||||
o.handlers[method][path] = builder(h)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -26,10 +29,10 @@ 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.
|
||||
|
||||
*/
|
||||
type Healthz struct {
|
||||
Context *middleware.Context
|
||||
@@ -48,7 +51,6 @@ func (o *Healthz) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
res := o.Handler.Handle(Params) // actually handle the request
|
||||
|
||||
o.Context.Respond(rw, r, route.Produces, route, res)
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -22,6 +25,7 @@ func NewHealthzParams() HealthzParams {
|
||||
//
|
||||
// swagger:parameters healthz
|
||||
type HealthzParams struct {
|
||||
|
||||
// HTTP Request Object
|
||||
HTTPRequest *http.Request `json:"-"`
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -13,8 +16,7 @@ import (
|
||||
// HealthzOKCode is the HTTP code returned for type HealthzOK
|
||||
const HealthzOKCode int = 200
|
||||
|
||||
/*
|
||||
HealthzOK Health check report
|
||||
/*HealthzOK Health check report
|
||||
|
||||
swagger:response healthzOK
|
||||
*/
|
||||
@@ -58,8 +60,7 @@ func (o *HealthzOK) WriteResponse(rw http.ResponseWriter, producer runtime.Produ
|
||||
// HealthzServiceUnavailableCode is the HTTP code returned for type HealthzServiceUnavailable
|
||||
const HealthzServiceUnavailableCode int = 503
|
||||
|
||||
/*
|
||||
HealthzServiceUnavailable Unhealthy service
|
||||
/*HealthzServiceUnavailable Unhealthy service
|
||||
|
||||
swagger:response healthzServiceUnavailable
|
||||
*/
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -26,10 +29,10 @@ 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
|
||||
|
||||
*/
|
||||
type Ping struct {
|
||||
Context *middleware.Context
|
||||
@@ -48,7 +51,6 @@ func (o *Ping) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
res := o.Handler.Handle(Params) // actually handle the request
|
||||
|
||||
o.Context.Respond(rw, r, route.Produces, route, res)
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -22,6 +25,7 @@ func NewPingParams() PingParams {
|
||||
//
|
||||
// swagger:parameters ping
|
||||
type PingParams struct {
|
||||
|
||||
// HTTP Request Object
|
||||
HTTPRequest *http.Request `json:"-"`
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -13,8 +16,7 @@ import (
|
||||
// PingOKCode is the HTTP code returned for type PingOK
|
||||
const PingOKCode int = 200
|
||||
|
||||
/*
|
||||
PingOK return success
|
||||
/*PingOK return success
|
||||
|
||||
swagger:response pingOK
|
||||
*/
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
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"
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -18,11 +20,10 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
flags "github.com/jessevdk/go-flags"
|
||||
"golang.org/x/net/netutil"
|
||||
|
||||
"github.com/go-openapi/runtime/flagext"
|
||||
"github.com/go-openapi/swag"
|
||||
flags "github.com/jessevdk/go-flags"
|
||||
"golang.org/x/net/netutil"
|
||||
|
||||
"github.com/bloomberg/goldpinger/v3/pkg/restapi/operations"
|
||||
)
|
||||
@@ -80,7 +81,7 @@ type Server struct {
|
||||
ListenLimit int `long:"listen-limit" description:"limit the number of outstanding requests"`
|
||||
KeepAlive time.Duration `long:"keep-alive" description:"sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)" default:"3m"`
|
||||
ReadTimeout time.Duration `long:"read-timeout" description:"maximum duration before timing out read of the request" default:"30s"`
|
||||
WriteTimeout time.Duration `long:"write-timeout" description:"maximum duration before timing out write of the response" default:"30s"`
|
||||
WriteTimeout time.Duration `long:"write-timeout" description:"maximum duration before timing out write of the response" default:"60s"`
|
||||
httpServerL net.Listener
|
||||
|
||||
TLSHost string `long:"tls-host" description:"the IP to listen on for tls, when not specified it's the same as --host" env:"TLS_HOST"`
|
||||
@@ -104,7 +105,7 @@ type Server struct {
|
||||
}
|
||||
|
||||
// Logf logs message either via defined user logger or via system one if no user logger is defined.
|
||||
func (s *Server) Logf(f string, args ...any) {
|
||||
func (s *Server) Logf(f string, args ...interface{}) {
|
||||
if s.api != nil && s.api.Logger != nil {
|
||||
s.api.Logger(f, args...)
|
||||
} else {
|
||||
@@ -114,7 +115,7 @@ func (s *Server) Logf(f string, args ...any) {
|
||||
|
||||
// Fatalf logs message either via defined user logger or via system one if no user logger is defined.
|
||||
// Exits with non-zero status after printing
|
||||
func (s *Server) Fatalf(f string, args ...any) {
|
||||
func (s *Server) Fatalf(f string, args ...interface{}) {
|
||||
if s.api != nil && s.api.Logger != nil {
|
||||
s.api.Logger(f, args...)
|
||||
os.Exit(1)
|
||||
@@ -188,8 +189,8 @@ func (s *Server) Serve() (err error) {
|
||||
s.Logf("Serving goldpinger at unix://%s", s.SocketPath)
|
||||
go func(l net.Listener) {
|
||||
defer wg.Done()
|
||||
if errServe := domainSocket.Serve(l); errServe != nil && !errors.Is(errServe, http.ErrServerClosed) {
|
||||
s.Fatalf("%v", errServe)
|
||||
if err := domainSocket.Serve(l); err != nil && err != http.ErrServerClosed {
|
||||
s.Fatalf("%v", err)
|
||||
}
|
||||
s.Logf("Stopped serving goldpinger at unix://%s", s.SocketPath)
|
||||
}(s.domainSocketL)
|
||||
@@ -218,8 +219,8 @@ func (s *Server) Serve() (err error) {
|
||||
s.Logf("Serving goldpinger at http://%s", s.httpServerL.Addr())
|
||||
go func(l net.Listener) {
|
||||
defer wg.Done()
|
||||
if errServe := httpServer.Serve(l); errServe != nil && !errors.Is(errServe, http.ErrServerClosed) {
|
||||
s.Fatalf("%v", errServe)
|
||||
if err := httpServer.Serve(l); err != nil && err != http.ErrServerClosed {
|
||||
s.Fatalf("%v", err)
|
||||
}
|
||||
s.Logf("Stopped serving goldpinger at http://%s", l.Addr())
|
||||
}(s.httpServerL)
|
||||
@@ -273,14 +274,14 @@ func (s *Server) Serve() (err error) {
|
||||
|
||||
if s.TLSCACertificate != "" {
|
||||
// include specified CA certificate
|
||||
caCert, caCertErr := os.ReadFile(string(s.TLSCACertificate))
|
||||
caCert, caCertErr := ioutil.ReadFile(string(s.TLSCACertificate))
|
||||
if caCertErr != nil {
|
||||
return caCertErr
|
||||
}
|
||||
caCertPool := x509.NewCertPool()
|
||||
ok := caCertPool.AppendCertsFromPEM(caCert)
|
||||
if !ok {
|
||||
return errors.New("cannot parse CA certificate")
|
||||
return fmt.Errorf("cannot parse CA certificate")
|
||||
}
|
||||
httpsServer.TLSConfig.ClientCAs = caCertPool
|
||||
httpsServer.TLSConfig.ClientAuth = tls.RequireAndVerifyClientCert
|
||||
@@ -311,8 +312,8 @@ func (s *Server) Serve() (err error) {
|
||||
s.Logf("Serving goldpinger at https://%s", s.httpsServerL.Addr())
|
||||
go func(l net.Listener) {
|
||||
defer wg.Done()
|
||||
if errServe := httpsServer.Serve(l); errServe != nil && !errors.Is(errServe, http.ErrServerClosed) {
|
||||
s.Fatalf("%v", errServe)
|
||||
if err := httpsServer.Serve(l); err != nil && err != http.ErrServerClosed {
|
||||
s.Fatalf("%v", err)
|
||||
}
|
||||
s.Logf("Stopped serving goldpinger at https://%s", l.Addr())
|
||||
}(tls.NewListener(s.httpsServerL, httpsServer.TLSConfig))
|
||||
|
||||
@@ -378,33 +378,16 @@ var main = function(timeout){
|
||||
if (!edge._data.OK) {
|
||||
color = "red";
|
||||
}
|
||||
if (edge._data.OK && edge._data["loss-pct"] > 0) {
|
||||
color = "#f0ad4e";
|
||||
}
|
||||
if ("isprobeResultsNode" in edge._data) {
|
||||
type = "dashed";
|
||||
}
|
||||
var label = "";
|
||||
if (edge._data["udp-rtt-ms"] > 0) {
|
||||
label = edge._data["udp-rtt-ms"].toFixed(2) + "ms udp";
|
||||
} else if (edge._data["response-time-ms"]) {
|
||||
label = edge._data["response-time-ms"] + "ms";
|
||||
} else if (edge._data.elapsed) {
|
||||
label = edge._data.elapsed;
|
||||
}
|
||||
if (edge._data["loss-pct"] > 0) {
|
||||
label += " " + edge._data["loss-pct"].toFixed(1) + "% loss";
|
||||
}
|
||||
if (edge._data["hop-count"] > 0) {
|
||||
label += " " + edge._data["hop-count"] + " hops";
|
||||
}
|
||||
var edge = {
|
||||
id: "e" + i,
|
||||
source: edge.source,
|
||||
target: edge.target,
|
||||
type: type,
|
||||
color: color,
|
||||
label: label,
|
||||
label: edge._data.elapsed,
|
||||
size: 7
|
||||
}
|
||||
//console.log(edge);
|
||||
|
||||
12
swagger.yml
12
swagger.yml
@@ -61,18 +61,6 @@ definitions:
|
||||
type: number
|
||||
format: int64
|
||||
description: wall clock time in milliseconds
|
||||
loss-pct:
|
||||
type: number
|
||||
format: double
|
||||
description: UDP packet loss percentage (0-100)
|
||||
hop-count:
|
||||
type: integer
|
||||
format: int32
|
||||
description: estimated network hop count from UDP TTL
|
||||
udp-rtt-ms:
|
||||
type: number
|
||||
format: double
|
||||
description: average UDP round-trip time in milliseconds
|
||||
CheckResults:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
Reference in New Issue
Block a user