33 Commits
1.5.0 ... 2.0.0

Author SHA1 Message Date
Mikolaj Pawlikowski
f99ba84d17 Merge pull request #64 from seeker89/bump-major-version
Add info on how to use the DNS features
2019-09-06 15:10:44 +01:00
Mikolaj Pawlikowski
75315a872a Better wording in the README
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-09-06 14:58:10 +01:00
Mikolaj Pawlikowski
ae67cf3594 Add a note about the DNS addresses being space-delimited
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-09-06 14:57:08 +01:00
Mikolaj Pawlikowski
433a6b8b88 Add a note about the DNS usage
Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-09-06 14:51:22 +01:00
Mikolaj Pawlikowski
0660db7922 Bump up major version to 2.0.0
Since this is effectively a backwards incompatible change

Signed-off-by: Mikolaj Pawlikowski <mikolaj@pawlikowski.pl>
2019-09-06 14:42:36 +01:00
Mikolaj Pawlikowski
58285945f6 Merge pull request #61 from cgreen12/master
Optionally test DNS resolution for each pod
2019-09-06 12:23:36 +01:00
Mikolaj Pawlikowski
8a014ad7f4 Merge branch 'master' into master 2019-09-05 13:58:20 +01:00
Mikolaj Pawlikowski
096b149afa Merge pull request #63 from ufou/all_relative_paths
make all paths relative to allow for hosting at a sub path of root
2019-09-05 13:56:58 +01:00
Luke Alexander
5840353d9f bump patch version accordingly
Signed-off-by: Luke Alexander <luke.alexander@mixcloud.com>
2019-09-05 11:39:50 +01:00
Luke Alexander
ac9bf4224d make all paths relative to allow for hosting at a sub path of root
Signed-off-by: Luke Alexander <luke.alexander@mixcloud.com>
2019-09-05 11:10:23 +01:00
Chris Green
bcbc2ac6fc :trollface: re-ran swagger
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-08-21 04:53:01 -04:00
Chris Green
192fc433a2 Added metric for DNS failures
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-07-04 03:06:29 -04:00
Chris Green
dc3864f170 Colour the dns nodes red for any failures
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-09 09:11:49 -04:00
Chris Green
8a759433eb Show the info for dns nodes
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-09 08:53:52 -04:00
Chris Green
1b12b7dc6b Version bump
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-09 08:44:49 -04:00
Chris Green
9adf26e2cb Consistency ftw
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-09 08:43:47 -04:00
Chris Green
927125bbc5 slight re-positioning
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-09 07:37:48 -04:00
Chris Green
7585d010a6 Initial UI changes
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-05 14:56:37 -04:00
Chris Green
5e0ecdd8d1 Updates from swagger change
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-05 14:30:53 -04:00
Chris Green
d834433d30 Moved dns check into client
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-05 14:30:11 -04:00
Chris Green
b64f5152f2 Moved DnsResults into CheckResults
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-05 14:28:40 -04:00
Chris Green
bbac97c17e Refactored swagger.yml for fewer dns requests
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-04 02:54:23 -04:00
Chris Green
74ffcc8d2e Do the dns lookup
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-02 13:18:40 -04:00
Chris Green
9586e16237 Updated models from swagger
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-02 13:18:05 -04:00
Chris Green
6541250aa9 Updated swagger.yml for map of dnsresults
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-02 11:54:20 -04:00
Chris Green
31a503d831 Added env-delim for envvar config
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-02 11:18:25 -04:00
Chris Green
195691518b Added DnsHosts to config
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-01 15:18:26 -04:00
Chris Green
aa66c94d47 Initial thoughts on swagger change
Signed-off-by: Chris Green <34572557+cgreen12@users.noreply.github.com>
2019-06-01 11:41:01 -04:00
Mikolaj Pawlikowski
7b2affea29 Merge pull request #59 from kpfleming/travis-deploy-one-version
Ensure that only Golang 1.10 builds are pushed to DockerHub
2019-03-22 15:27:12 +00:00
Kevin P. Fleming
d1a86eae93 Ensure that only Golang 1.10 builds are pushed to DockerHub
Signed-off-by: Kevin P. Fleming <kpfleming@bloomberg.net>
2019-03-21 16:16:22 -04:00
Mikolaj Pawlikowski
a2e5925210 Merge pull request #58 from dannyk81/healthz_readme
Update readme and example with liveness and readiness probes
2019-03-18 09:56:04 +00:00
Danny Kulchinsky
d243f0fb59 update example
Signed-off-by: Danny Kulchinsky <danny.kul@gmail.com>
Signed-off-by: Danny Kulchinsky <dannyk@tuenti.com>
2019-03-17 21:01:15 -04:00
Danny Kulchinsky
477ba69a72 Add livenessProbe and readinessProbe to README
Signed-off-by: Danny Kulchinsky <danny.kul@gmail.com>
Signed-off-by: Danny Kulchinsky <dannyk@tuenti.com>
2019-03-17 21:01:15 -04:00
23 changed files with 473 additions and 63 deletions

View File

@@ -36,4 +36,5 @@ deploy:
skip_cleanup: true
on:
tags: true
go: "1.10.x"
condition: -n "$DOCKER_PASSWORD"

View File

@@ -1,5 +1,5 @@
name ?= goldpinger
version ?= 1.5.0
version ?= 2.0.0
bin ?= goldpinger
pkg ?= "github.com/bloomberg/goldpinger"
tag = $(name):$(version)

View File

@@ -18,6 +18,7 @@ Oh, and it gives you the graph below for your cluster. Check out the [video expl
- [Installation](#installation)
- [Authentication with Kubernetes API](#authentication-with-kubernetes-api)
- [Example YAML](#example-yaml)
- [Note on DNS](#note-on-dns)
- [Usage](#usage)
- [UI](#ui)
- [API](#api)
@@ -126,12 +127,12 @@ spec:
selector:
matchLabels:
app: goldpinger
version: "1.0.0"
version: "1.5.0"
template:
metadata:
labels:
app: goldpinger
version: "1.0.0"
version: "1.5.0"
spec:
containers:
- name: goldpinger
@@ -150,10 +151,22 @@ spec:
valueFrom:
fieldRef:
fieldPath: status.podIP
image: "docker.io/bloomberg/goldpinger:1.4.0"
image: "docker.io/bloomberg/goldpinger:1.5.0"
ports:
- containerPort: 80
name: http
readinessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 20
periodSeconds: 5
livenessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 20
periodSeconds: 5
---
apiVersion: v1
kind: Service
@@ -191,6 +204,28 @@ subjects:
You can also see [an example of using `kubeconfig` in the `./extras`](./extras/example-with-kubeconfig.yaml).
### Note on DNS
Note, that on top of resolving the other pods, all instances can also try to resolve arbitrary DNS. This allows you to test your DNS setup.
From `--help`:
```sh
--host-to-resolve= A host to attempt dns resolve on (space delimited) [$HOSTS_TO_RESOLVE]
```
So in order to test two domains, we could add an extra env var to the example above:
```yaml
- name: HOSTS_TO_RESOLVE
value: "www.bloomberg.com one.two.three"
```
and `goldpinger` should show something like this:
![screenshot-DNS-resolution](./extras/dns-screenshot.png)
## Usage
### UI

BIN
extras/dns-screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

View File

@@ -5,19 +5,19 @@ metadata:
name: goldpinger
labels:
app: goldpinger
version: "1.1.0"
version: "1.5.0"
spec:
updateStrategy:
type: RollingUpdate
selector:
matchLabels:
app: goldpinger
version: "1.1.0"
version: "1.5.0"
template:
metadata:
labels:
app: goldpinger
version: "1.1.0"
version: "1.5.0"
spec:
# if you'd like to use a secret to inject a kubeconfig, you can do it like this
volumes:
@@ -48,10 +48,22 @@ spec:
valueFrom:
fieldRef:
fieldPath: status.podIP
image: "docker.io/bloomberg/goldpinger:1.4.0"
image: "docker.io/bloomberg/goldpinger:1.5.0"
ports:
- containerPort: 80
name: http
readinessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 20
periodSeconds: 5
livenessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 20
periodSeconds: 5
volumeMounts:
- mountPath: /.kube/
name: kubeconfig

View File

@@ -47,7 +47,7 @@ func NewCheckServicePodsOK() *CheckServicePodsOK {
Success, return response
*/
type CheckServicePodsOK struct {
Payload models.CheckResults
Payload *models.CheckResults
}
func (o *CheckServicePodsOK) Error() string {
@@ -56,8 +56,10 @@ func (o *CheckServicePodsOK) Error() string {
func (o *CheckServicePodsOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(models.CheckResults)
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}

View File

@@ -16,6 +16,7 @@ package goldpinger
import (
"fmt"
"net"
"sync"
"time"
@@ -27,7 +28,7 @@ import (
// CheckNeighbours queries the kubernetes API server for all other goldpinger pods
// then calls Ping() on each one
func CheckNeighbours(ps *PodSelecter) models.CheckResults {
func CheckNeighbours(ps *PodSelecter) *models.CheckResults {
return PingAllPods(ps.SelectPods())
}
@@ -50,7 +51,25 @@ func pickPodHostIP(podIP, hostIP string) string {
return podIP
}
func PingAllPods(pods map[string]string) models.CheckResults {
func checkDNS() *models.DNSResults {
results := models.DNSResults{}
for _, host := range GoldpingerConfig.DnsHosts{
var dnsResult models.DNSResult
start := time.Now()
_, err := net.LookupIP(host)
if err != nil {
dnsResult.Error = err.Error()
CountDnsError(host)
}
dnsResult.ResponseTimeMs = time.Since(start).Nanoseconds() / int64(time.Millisecond)
results[host] = dnsResult
}
return &results
}
func PingAllPods(pods map[string]string) *models.CheckResults {
result := models.CheckResults{}
@@ -84,11 +103,15 @@ func PingAllPods(pods map[string]string) models.CheckResults {
wg.Done()
}(podIP, hostIP)
}
if len(GoldpingerConfig.DnsHosts) > 0 {
result.DNSResults = *checkDNS()
}
wg.Wait()
close(ch)
counterHealthy, counterUnhealthy := 0.0, 0.0
result.PodResults = make(map[string]models.PodResult)
for response := range ch {
var podIPv4 strfmt.IPv4
podIPv4.UnmarshalText([]byte(response.podIP))
@@ -97,10 +120,10 @@ func PingAllPods(pods map[string]string) models.CheckResults {
} else {
counterUnhealthy++
}
result[response.podIP] = response.podResult
result.PodResults[response.podIP] = response.podResult
}
CountHealthyUnhealthyNodes(counterHealthy, counterUnhealthy)
return result
return &result
}
type CheckServicePodsResult struct {
@@ -161,6 +184,18 @@ func CheckAllPods(pods map[string]string) *models.CheckAllResults {
HostIP: response.hostIPv4,
PodIP: podIPv4,
})
if response.checkAllPodResult.Response != nil &&
response.checkAllPodResult.Response.DNSResults != nil {
if result.DNSResults == nil {
result.DNSResults = make(map[string]models.DNSResults)
}
for host := range response.checkAllPodResult.Response.DNSResults {
if result.DNSResults[host] == nil {
result.DNSResults[host] = make(map[string]models.DNSResult)
}
result.DNSResults[host][response.podIP] = response.checkAllPodResult.Response.DNSResults[host]
}
}
}
return &result
}

View File

@@ -31,4 +31,6 @@ var GoldpingerConfig = struct {
LabelSelector string `long:"label-selector" description:"label selector to use to discover goldpinger pods in the cluster" env:"LABEL_SELECTOR" default:"app=goldpinger"`
KubernetesClient *kubernetes.Clientset
*PodSelecter
DnsHosts []string `long:"host-to-resolve" description:"A host to attempt dns resolve on (space delimited)" env:"HOSTS_TO_RESOLVE" env-delim:" "`
}{}

View File

@@ -115,7 +115,7 @@ func HeatmapHandler(w http.ResponseWriter, r *http.Request) {
// draw all the boxes
for sourceIP, results := range checkResults.Responses {
if *results.OK {
for destinationIP, response := range results.Response {
for destinationIP, response := range results.Response.PodResults {
x, y := getPingBoxCoordinates(order[sourceIP], order[destinationIP], boxSize, paddingSize)
color := getPingBoxColor(response.ResponseTimeMs, tresholdLatencies)
drawPingBox(canvas, boxSize+x, boxSize+y, boxSize, color)

View File

@@ -82,6 +82,16 @@ var (
"type",
},
)
goldpingerDnsErrorsCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "goldpinger_dns_errors_total",
Help: "Statistics of DNS errors per instance",
},
[]string{
"goldpinger_instance",
"host",
},
)
bootTime = time.Now()
)
@@ -92,6 +102,7 @@ func init() {
prometheus.MustRegister(goldpingerResponseTimePeersHistogram)
prometheus.MustRegister(goldpingerResponseTimeKubernetesHistogram)
prometheus.MustRegister(goldpingerErrorsCounter)
prometheus.MustRegister(goldpingerDnsErrorsCounter)
log.Println("Metrics setup - see /metrics")
}
@@ -131,6 +142,14 @@ func CountError(errorType string) {
).Inc()
}
// counts instances of dns errors
func CountDnsError(host string) {
goldpingerDnsErrorsCounter.WithLabelValues(
GoldpingerConfig.Hostname,
host,
).Inc()
}
// returns a timer for easy observing of the durations of calls to kubernetes API
func GetLabeledKubernetesCallsTimer() *prometheus.Timer {
return prometheus.NewTimer(

View File

@@ -31,7 +31,7 @@ func StartUpdater() {
for {
results := PingAllPods(GoldpingerConfig.PodSelecter.SelectPods())
var troublemakers []string
for podIP, value := range results {
for podIP, value := range results.PodResults {
if *value.OK != true {
troublemakers = append(troublemakers, fmt.Sprintf("%s (%s)", podIP, value.HostIP.String()))
}

View File

@@ -28,7 +28,7 @@ type CheckAllPodResult struct {
Error string `json:"error,omitempty"`
// response
Response CheckResults `json:"response,omitempty"`
Response *CheckResults `json:"response,omitempty"`
// status code
StatusCode int32 `json:"status-code,omitempty"`
@@ -71,11 +71,13 @@ func (m *CheckAllPodResult) validateResponse(formats strfmt.Registry) error {
return nil
}
if err := m.Response.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("response")
if m.Response != nil {
if err := m.Response.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("response")
}
return err
}
return err
}
return nil

View File

@@ -22,6 +22,9 @@ type CheckAllResults struct {
// o k
OK *bool `json:"OK,omitempty"`
// dns results
DNSResults map[string]DNSResults `json:"dnsResults,omitempty"`
// hosts
Hosts []*CheckAllResultsHostsItems0 `json:"hosts"`
@@ -39,6 +42,10 @@ type CheckAllResults struct {
func (m *CheckAllResults) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateDNSResults(formats); err != nil {
res = append(res, err)
}
if err := m.validateHosts(formats); err != nil {
res = append(res, err)
}
@@ -53,6 +60,25 @@ func (m *CheckAllResults) Validate(formats strfmt.Registry) error {
return nil
}
func (m *CheckAllResults) validateDNSResults(formats strfmt.Registry) error {
if swag.IsZero(m.DNSResults) { // not required
return nil
}
for k := range m.DNSResults {
if val, ok := m.DNSResults[k]; ok {
if err := val.Validate(formats); err != nil {
return err
}
}
}
return nil
}
func (m *CheckAllResults) validateHosts(formats strfmt.Registry) error {
if swag.IsZero(m.Hosts) { // not required

View File

@@ -9,28 +9,31 @@ import (
strfmt "github.com/go-openapi/strfmt"
"github.com/go-openapi/errors"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// CheckResults check results
// swagger:model CheckResults
type CheckResults map[string]PodResult
type CheckResults struct {
// dns results
DNSResults DNSResults `json:"dnsResults,omitempty"`
// pod results
PodResults map[string]PodResult `json:"podResults,omitempty"`
}
// Validate validates this check results
func (m CheckResults) Validate(formats strfmt.Registry) error {
func (m *CheckResults) Validate(formats strfmt.Registry) error {
var res []error
for k := range m {
if err := validate.Required(k, "body", m[k]); err != nil {
return err
}
if val, ok := m[k]; ok {
if err := val.Validate(formats); err != nil {
return err
}
}
if err := m.validateDNSResults(formats); err != nil {
res = append(res, err)
}
if err := m.validatePodResults(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
@@ -38,3 +41,59 @@ func (m CheckResults) Validate(formats strfmt.Registry) error {
}
return nil
}
func (m *CheckResults) validateDNSResults(formats strfmt.Registry) error {
if swag.IsZero(m.DNSResults) { // not required
return nil
}
if err := m.DNSResults.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("dnsResults")
}
return err
}
return nil
}
func (m *CheckResults) validatePodResults(formats strfmt.Registry) error {
if swag.IsZero(m.PodResults) { // not required
return nil
}
for k := range m.PodResults {
if err := validate.Required("podResults"+"."+k, "body", m.PodResults[k]); err != nil {
return err
}
if val, ok := m.PodResults[k]; ok {
if err := val.Validate(formats); err != nil {
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *CheckResults) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *CheckResults) UnmarshalBinary(b []byte) error {
var res CheckResults
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

46
pkg/models/dns_result.go Normal file
View File

@@ -0,0 +1,46 @@
// Code generated by go-swagger; DO NOT EDIT.
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
strfmt "github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// DNSResult Dns result
// swagger:model DnsResult
type DNSResult struct {
// error
Error string `json:"error,omitempty"`
// response time ms
ResponseTimeMs int64 `json:"response-time-ms,omitempty"`
}
// Validate validates this Dns result
func (m *DNSResult) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *DNSResult) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *DNSResult) UnmarshalBinary(b []byte) error {
var res DNSResult
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

40
pkg/models/dns_results.go Normal file
View File

@@ -0,0 +1,40 @@
// Code generated by go-swagger; DO NOT EDIT.
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
strfmt "github.com/go-openapi/strfmt"
"github.com/go-openapi/errors"
"github.com/go-openapi/validate"
)
// DNSResults Dns results
// swagger:model DnsResults
type DNSResults map[string]DNSResult
// Validate validates this Dns results
func (m DNSResults) Validate(formats strfmt.Registry) error {
var res []error
for k := range m {
if err := validate.Required(k, "body", m[k]); err != nil {
return err
}
if val, ok := m[k]; ok {
if err := val.Validate(formats); err != nil {
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

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

View File

@@ -21,7 +21,7 @@ func init() {
"swagger": "2.0",
"info": {
"title": "Goldpinger",
"version": "1.0.0"
"version": "2.0.0"
},
"paths": {
"/check": {
@@ -143,6 +143,12 @@ func init() {
"type": "boolean",
"default": false
},
"dnsResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/DnsResults"
}
},
"hosts": {
"type": "array",
"items": {
@@ -176,9 +182,34 @@ func init() {
}
},
"CheckResults": {
"type": "object",
"properties": {
"dnsResults": {
"$ref": "#/definitions/DnsResults"
},
"podResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/PodResult"
}
}
}
},
"DnsResult": {
"properties": {
"error": {
"type": "string"
},
"response-time-ms": {
"type": "number",
"format": "int64"
}
}
},
"DnsResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/PodResult"
"$ref": "#/definitions/DnsResult"
}
},
"HealthCheckResults": {
@@ -244,7 +275,7 @@ func init() {
"swagger": "2.0",
"info": {
"title": "Goldpinger",
"version": "1.0.0"
"version": "2.0.0"
},
"paths": {
"/check": {
@@ -366,6 +397,12 @@ func init() {
"type": "boolean",
"default": false
},
"dnsResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/DnsResults"
}
},
"hosts": {
"type": "array",
"items": {
@@ -399,9 +436,34 @@ func init() {
}
},
"CheckResults": {
"type": "object",
"properties": {
"dnsResults": {
"$ref": "#/definitions/DnsResults"
},
"podResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/PodResult"
}
}
}
},
"DnsResult": {
"properties": {
"error": {
"type": "string"
},
"response-time-ms": {
"type": "number",
"format": "int64"
}
}
},
"DnsResults": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/PodResult"
"$ref": "#/definitions/DnsResult"
}
},
"HealthCheckResults": {

View File

@@ -25,7 +25,7 @@ type CheckServicePodsOK struct {
/*
In: Body
*/
Payload models.CheckResults `json:"body,omitempty"`
Payload *models.CheckResults `json:"body,omitempty"`
}
// NewCheckServicePodsOK creates CheckServicePodsOK with default headers values
@@ -35,13 +35,13 @@ func NewCheckServicePodsOK() *CheckServicePodsOK {
}
// WithPayload adds the payload to the check service pods o k response
func (o *CheckServicePodsOK) WithPayload(payload models.CheckResults) *CheckServicePodsOK {
func (o *CheckServicePodsOK) WithPayload(payload *models.CheckResults) *CheckServicePodsOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the check service pods o k response
func (o *CheckServicePodsOK) SetPayload(payload models.CheckResults) {
func (o *CheckServicePodsOK) SetPayload(payload *models.CheckResults) {
o.Payload = payload
}
@@ -49,13 +49,10 @@ func (o *CheckServicePodsOK) SetPayload(payload models.CheckResults) {
func (o *CheckServicePodsOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
payload := o.Payload
if payload == nil {
// return empty map
payload = models.CheckResults{}
}
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View File

@@ -65,13 +65,13 @@ type GoldpingerAPI struct {
Middleware func(middleware.Builder) http.Handler
// BasicAuthenticator generates a runtime.Authenticator from the supplied basic auth function.
// It has a default implemention in the security package, however you can replace it for your particular usage.
// It has a default implementation in the security package, however you can replace it for your particular usage.
BasicAuthenticator func(security.UserPassAuthentication) runtime.Authenticator
// APIKeyAuthenticator generates a runtime.Authenticator from the supplied token auth function.
// It has a default implemention in the security package, however you can replace it for your particular usage.
// It has a default implementation in the security package, however you can replace it for your particular usage.
APIKeyAuthenticator func(string, string, security.TokenAuthentication) runtime.Authenticator
// BearerAuthenticator generates a runtime.Authenticator from the supplied bearer token auth function.
// It has a default implemention in the security package, however you can replace it for your particular usage.
// It has a default implementation in the security package, however you can replace it for your particular usage.
BearerAuthenticator func(string, security.ScopedTokenAuthentication) runtime.Authenticator
// JSONConsumer registers a consumer for a "application/json" mime type

View File

@@ -87,7 +87,7 @@ type Server struct {
TLSHost string `long:"tls-host" description:"the IP to listen on for tls, when not specified it's the same as --host" env:"TLS_HOST"`
TLSPort int `long:"tls-port" description:"the port to listen on for secure connections, defaults to a random value" env:"TLS_PORT"`
TLSCertificate flags.Filename `long:"tls-certificate" description:"the certificate to use for secure connections" env:"TLS_CERTIFICATE"`
TLSCertificateKey flags.Filename `long:"tls-key" description:"the private key to use for secure conections" env:"TLS_PRIVATE_KEY"`
TLSCertificateKey flags.Filename `long:"tls-key" description:"the private key to use for secure connections" env:"TLS_PRIVATE_KEY"`
TLSCACertificate flags.Filename `long:"tls-ca" description:"the certificate authority file to be used with mutual tls auth" env:"TLS_CA_CERTIFICATE"`
TLSListenLimit int `long:"tls-listen-limit" description:"limit the number of outstanding requests"`
TLSKeepAlive time.Duration `long:"tls-keep-alive" description:"sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)"`

View File

@@ -49,7 +49,7 @@ limitations under the License.
<script type="text/javascript" src="static/sigma.js/1.1.0/plugins/sigma.renderers.parallelEdges.min.js"></script>
<script type="text/javascript" src="static/sigma.js/1.1.0/plugins/sigma.renderers.snapshot.min.js"></script>
<script type="text/javascript" src="static/sigma.js/1.1.0/plugins/sigma.statistics.HITS.min.js"></script>
<!-- Bootstrap -->
<link rel="stylesheet" href="static/bootstrap/3.3.7/css/bootstrap.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="static/bootstrap/3.3.7/css/bootstrap-theme.min.css" crossorigin="anonymous">
@@ -219,7 +219,7 @@ var main = function(timeout){
loadingDialog(true);
fetchJSON("/check_all?timeout="+timeout)
fetchJSON("check_all?timeout="+timeout)
.then(function(data){
loadingDialog(false);
@@ -229,6 +229,7 @@ var main = function(timeout){
// prepare nodes
var nodes = [];
var dnsCheckNodes = [];
var podIPs = [];
var resp = data.responses;
for (let podIP in resp) {
@@ -247,7 +248,7 @@ var main = function(timeout){
var edges = [];
var resp = data.responses;
for (let callId in resp) {
var call = resp[callId].response;
var call = resp[callId].response['podResults'];
if (typeof call !== 'string'){
for (let target in call) {
edges.push({
@@ -258,6 +259,7 @@ var main = function(timeout){
};
}
};
console.log(edges);
console.log(nodes);
@@ -279,6 +281,39 @@ var main = function(timeout){
})
console.log(nodes);
if ('dnsResults' in data) {
var yoffset = 0;
for (let checkedHost in data.dnsResults) {
let value = data.dnsResults[checkedHost];
var allOk = true;
for (let pod in value) {
var podData = value[pod];
var elapsed = 0;
if ('response-time-ms' in podData) {
elapsed = podData['response-time-ms'];
}
var podOk = (!('error' in podData));
allOk = allOk && podOk
edges.push({
source: pod,
target: checkedHost,
_data: {
"OK": podOk,
"elapsed": elapsed,
"isDNSCheckNode": true,
}
});
}
value["OK"] = allOk
dnsCheckNodes.push({
"label": checkedHost,
"id": checkedHost,
"x": 0,
"y": 0,
_data: value,
});
}
}
// build the actual graph
s = new sigma({
@@ -311,6 +346,19 @@ var main = function(timeout){
s.graph.addNode(node);
});
// generate any dns nodes on the graph
dnsCheckNodes.forEach(function(node, i, a){
node.x = 2;
node.y = (0.6 * i / a.length) - 0.8;
node.size = 10;
node.color = "#4CC40B";
if (!node._data.OK) {
node.color = "red";
}
//console.log(node);
s.graph.addNode(node);
});
// generate the edges
edges.forEach(function(edge, i){
var color = "#ccc";
@@ -322,6 +370,9 @@ var main = function(timeout){
if (!edge._data.OK) {
color = "red";
}
if ("isDNSCheckNode" in edge._data) {
type = "dashed";
}
var edge = {
id: "e" + i,
source: edge.source,
@@ -372,7 +423,7 @@ var main = function(timeout){
$('#modal-title').html(node.id);
$('#modal-body').html(prepareJSON(node._data));
// show the things
// show the things
$('#modal-window-code').modal('show');
});
s.bind("clickStage", function (e) {
@@ -388,7 +439,7 @@ var main = function(timeout){
$('#modal-title').html(edge.id);
$('#modal-body').html(prepareJSON(edge._data));
// show the things
// show the things
$('#modal-window-code').modal('show');
});
})
@@ -404,10 +455,10 @@ main();
$("#show-data").click(function (e) {
// fill the voids
$('#modal-title').html("/check_all");
$('#modal-title').html("check_all");
$('#modal-body').html(prepareJSON(global_data));
// show the things
// show the things
$('#modal-window-code').modal('show');
});
$("#reload-graph").click(function (e) {
@@ -431,3 +482,4 @@ $("#update-heatmap").click(function (e) {
</html>

View File

@@ -1,7 +1,7 @@
---
swagger: '2.0'
info:
version: 1.0.0
version: 2.0.0
title: Goldpinger
definitions:
CallStats:
@@ -12,6 +12,17 @@ definitions:
type: integer
ping:
type: integer
DnsResult:
properties:
response-time-ms:
type: number
format: int64
error:
type: string
DnsResults:
type: object
additionalProperties:
$ref: '#/definitions/DnsResult'
PingResults:
type: object
properties:
@@ -42,8 +53,13 @@ definitions:
description: wall clock time in milliseconds
CheckResults:
type: object
additionalProperties:
$ref: '#/definitions/PodResult'
properties:
dnsResults:
$ref: '#/definitions/DnsResults'
podResults:
type: object
additionalProperties:
$ref: '#/definitions/PodResult'
CheckAllPodResult:
type: object
properties:
@@ -83,6 +99,10 @@ definitions:
podIP:
type: string
format: ipv4
dnsResults:
type: object
additionalProperties:
$ref: '#/definitions/DnsResults'
responses:
type: object
additionalProperties: