Compare commits

...

25 Commits

Author SHA1 Message Date
semantic-release-bot
a9bb22f16c release(rc): v1.3.2-rc.3
## [1.3.2-rc.3](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.2-rc.2...v1.3.2-rc.3) (2024-08-20)

### Build system and dependencies

* **deps:** update all non-major dependencies ([65f30a6](65f30a6b09))
2024-08-20 21:18:09 +00:00
65f30a6b09 build(deps): update all non-major dependencies
All checks were successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/push/release Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
2024-08-20 21:15:17 +00:00
semantic-release-bot
c269e64231 release(rc): v1.3.2-rc.2
## [1.3.2-rc.2](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.2-rc.1...v1.3.2-rc.2) (2024-08-20)

### Build system and dependencies

* **deps:** update golang docker tag to v1.23 ([0ad5148](0ad514865c))
2024-08-20 20:46:31 +00:00
0ad514865c
build(deps): update golang docker tag to v1.23
All checks were successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/push/release Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
2024-08-20 22:45:44 +02:00
semantic-release-bot
8f8d6eb47f release(rc): v1.3.2-rc.1
## [1.3.2-rc.1](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1...v1.3.2-rc.1) (2024-08-20)

### Build system and dependencies

* **deps:** update all major dependencies ([48aa72b](48aa72b375))
2024-08-20 20:36:05 +00:00
48aa72b375 build(deps): update all major dependencies
All checks were successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/push/release Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
2024-06-01 00:02:40 +00:00
semantic-release-bot
7f5d2fd5e2 release(stable): v1.3.1
## [1.3.1](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.0...v1.3.1) (2024-05-27)

### Refactoring

* **formatting:** change line terminators from CRLF to LF ([ec44d7f](ec44d7f643))
* **probes:** rename `ProbeFunction` to `Probe` ([8dc7f27](8dc7f27400))

### Continuous Integrations

* **deps:** pin `conventional-changelog-conventionalcommits` to version 7.x ([b15846a](b15846aa58))
* **test:** remove `group` directive ([a1bab99](a1bab99cbd))

### Build system and dependencies

* **deps:** update all non-major dependencies ([a68663c](a68663cff0))
* **deps:** update dependency @semantic-release/commit-analyzer to v12 ([2a79a68](2a79a6878f))
* **deps:** update dependency @semantic-release/npm to v12 ([fdee33a](fdee33a1e7))
* **deps:** update dependency @semantic-release/release-notes-generator to v13 ([0cba4d2](0cba4d2a50))
* **deps:** update dependency conventional-changelog-conventionalcommits to v8 ([8918072](8918072d5c))
* **deps:** update dependency semantic-release to v23.0.3 ([cea539f](cea539fd6d))
* **deps:** update dependency semantic-release to v23.0.4 ([2d5b101](2d5b101b8d))
* **deps:** update dependency semantic-release to v23.0.5 ([061100e](061100e432))
* **deps:** update dependency semantic-release to v23.0.8 ([b98f6ef](b98f6ef609))
2024-05-27 23:55:53 +00:00
semantic-release-bot
e830e25560 release(rc): v1.3.1-rc.11
All checks were successful
ci/woodpecker/push/release Pipeline was successful
## [1.3.1-rc.11](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1-rc.10...v1.3.1-rc.11) (2024-05-27)

### Refactoring

* **formatting:** change line terminators from CRLF to LF ([ec44d7f](ec44d7f643))
2024-05-27 23:54:51 +00:00
ec44d7f643
refactor(formatting): change line terminators from CRLF to LF
All checks were successful
ci/woodpecker/push/release Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
2024-05-28 01:54:25 +02:00
df80db0e29
docs(readme): add badges 2024-05-28 01:54:24 +02:00
semantic-release-bot
c8471ec264 release(rc): v1.3.1-rc.10
## [1.3.1-rc.10](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1-rc.9...v1.3.1-rc.10) (2024-05-27)

### Continuous Integrations

* **test:** remove `group` directive ([a1bab99](a1bab99cbd))
2024-05-27 23:49:39 +00:00
7a54da4c57
docs(readme): update README.md
All checks were successful
ci/woodpecker/push/release Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
2024-05-28 01:43:09 +02:00
a1bab99cbd
ci(test): remove group directive 2024-05-28 01:39:29 +02:00
semantic-release-bot
eeb0d8f522 release(rc): v1.3.1-rc.9
## [1.3.1-rc.9](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1-rc.8...v1.3.1-rc.9) (2024-05-21)

### Continuous Integrations

* **deps:** pin `conventional-changelog-conventionalcommits` to version 7.x ([b15846a](b15846aa58))

### Build system and dependencies

* **deps:** update all non-major dependencies ([a68663c](a68663cff0))
* **deps:** update dependency conventional-changelog-conventionalcommits to v8 ([8918072](8918072d5c))
2024-05-21 21:01:49 +00:00
b15846aa58
ci(deps): pin conventional-changelog-conventionalcommits to version 7.x
All checks were successful
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/push/release Pipeline was successful
2024-05-21 23:00:55 +02:00
a68663cff0 build(deps): update all non-major dependencies
Some checks failed
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/push/release Pipeline failed
ci/woodpecker/push/test Pipeline was successful
2024-05-15 13:15:19 +02:00
8918072d5c build(deps): update dependency conventional-changelog-conventionalcommits to v8
Some checks failed
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/push/release Pipeline failed
ci/woodpecker/push/test Pipeline was successful
2024-05-04 00:02:17 +00:00
semantic-release-bot
71c370f53a release(rc): v1.3.1-rc.8
## [1.3.1-rc.8](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1-rc.7...v1.3.1-rc.8) (2024-04-12)

### Build system and dependencies

* **deps:** update dependency semantic-release to v23.0.8 ([b98f6ef](b98f6ef609))
2024-04-12 12:44:11 +00:00
b98f6ef609 build(deps): update dependency semantic-release to v23.0.8
All checks were successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/push/release Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
2024-04-12 12:41:33 +00:00
semantic-release-bot
16f29ebfc1 release(rc): v1.3.1-rc.7
## [1.3.1-rc.7](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1-rc.6...v1.3.1-rc.7) (2024-04-12)

### Build system and dependencies

* **deps:** update dependency @semantic-release/release-notes-generator to v13 ([0cba4d2](0cba4d2a50))
2024-04-12 12:39:03 +00:00
0cba4d2a50 build(deps): update dependency @semantic-release/release-notes-generator to v13
All checks were successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/push/release Pipeline was successful
2024-03-27 00:02:50 +00:00
semantic-release-bot
b441b35d48 release(rc): v1.3.1-rc.6
## [1.3.1-rc.6](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1-rc.5...v1.3.1-rc.6) (2024-03-23)

### Build system and dependencies

* **deps:** update dependency semantic-release to v23.0.5 ([061100e](061100e432))
2024-03-23 23:21:53 +00:00
061100e432 build(deps): update dependency semantic-release to v23.0.5
All checks were successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/push/release Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
2024-03-23 23:20:30 +00:00
semantic-release-bot
9288fcd144 release(rc): v1.3.1-rc.5
## [1.3.1-rc.5](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1-rc.4...v1.3.1-rc.5) (2024-03-23)

### Build system and dependencies

* **deps:** update dependency @semantic-release/commit-analyzer to v12 ([2a79a68](2a79a6878f))
2024-03-23 23:18:28 +00:00
2a79a6878f build(deps): update dependency @semantic-release/commit-analyzer to v12
All checks were successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/push/release Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
2024-03-19 00:02:43 +00:00
7 changed files with 2242 additions and 1279 deletions

View File

@ -5,7 +5,6 @@ when:
steps:
test:
group: test
image: golang:1.22-alpine
image: golang:1.23-alpine
commands:
- go test -v ./...

View File

@ -1,3 +1,103 @@
## [1.3.2-rc.3](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.2-rc.2...v1.3.2-rc.3) (2024-08-20)
### Build system and dependencies
* **deps:** update all non-major dependencies ([65f30a6](https://git.ext.icikowski.pl/go/kubeprobes/commit/65f30a6b09628b6e58f40318279e2034f92790ba))
## [1.3.2-rc.2](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.2-rc.1...v1.3.2-rc.2) (2024-08-20)
### Build system and dependencies
* **deps:** update golang docker tag to v1.23 ([0ad5148](https://git.ext.icikowski.pl/go/kubeprobes/commit/0ad514865ca927f9f87747b2710f6be9f8b43590))
## [1.3.2-rc.1](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1...v1.3.2-rc.1) (2024-08-20)
### Build system and dependencies
* **deps:** update all major dependencies ([48aa72b](https://git.ext.icikowski.pl/go/kubeprobes/commit/48aa72b3757830fb05ed136765cb7389ba1d7285))
## [1.3.1](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.0...v1.3.1) (2024-05-27)
### Refactoring
* **formatting:** change line terminators from CRLF to LF ([ec44d7f](https://git.ext.icikowski.pl/go/kubeprobes/commit/ec44d7f643e78cfb1e9724b36416458782a6c775))
* **probes:** rename `ProbeFunction` to `Probe` ([8dc7f27](https://git.ext.icikowski.pl/go/kubeprobes/commit/8dc7f27400075fabca9525f42eb20404736fb1cb))
### Continuous Integrations
* **deps:** pin `conventional-changelog-conventionalcommits` to version 7.x ([b15846a](https://git.ext.icikowski.pl/go/kubeprobes/commit/b15846aa58864f5809e2226cad9c52770f84aae9))
* **test:** remove `group` directive ([a1bab99](https://git.ext.icikowski.pl/go/kubeprobes/commit/a1bab99cbdbf903256be3172036fc9b8c44f9992))
### Build system and dependencies
* **deps:** update all non-major dependencies ([a68663c](https://git.ext.icikowski.pl/go/kubeprobes/commit/a68663cff022fa135d48fae6f00e39ea684983f1))
* **deps:** update dependency @semantic-release/commit-analyzer to v12 ([2a79a68](https://git.ext.icikowski.pl/go/kubeprobes/commit/2a79a6878f647049ca2f01711d74561f6c4974c6))
* **deps:** update dependency @semantic-release/npm to v12 ([fdee33a](https://git.ext.icikowski.pl/go/kubeprobes/commit/fdee33a1e7c05bd19f0f5d675df434ad4d844911))
* **deps:** update dependency @semantic-release/release-notes-generator to v13 ([0cba4d2](https://git.ext.icikowski.pl/go/kubeprobes/commit/0cba4d2a50319cc0250dc3cb14e32dee813b4fc0))
* **deps:** update dependency conventional-changelog-conventionalcommits to v8 ([8918072](https://git.ext.icikowski.pl/go/kubeprobes/commit/8918072d5c818bad10542957b93440730d50baf1))
* **deps:** update dependency semantic-release to v23.0.3 ([cea539f](https://git.ext.icikowski.pl/go/kubeprobes/commit/cea539fd6d68608635ec19ae8840da749695bfac))
* **deps:** update dependency semantic-release to v23.0.4 ([2d5b101](https://git.ext.icikowski.pl/go/kubeprobes/commit/2d5b101b8d38d7af7c6b4ba570f1045fe9e9dc7b))
* **deps:** update dependency semantic-release to v23.0.5 ([061100e](https://git.ext.icikowski.pl/go/kubeprobes/commit/061100e432a61ed6bcb310de297880db369e2f24))
* **deps:** update dependency semantic-release to v23.0.8 ([b98f6ef](https://git.ext.icikowski.pl/go/kubeprobes/commit/b98f6ef609c278bfbd25c25316ad166fba75f255))
## [1.3.1-rc.11](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1-rc.10...v1.3.1-rc.11) (2024-05-27)
### Refactoring
* **formatting:** change line terminators from CRLF to LF ([ec44d7f](https://git.ext.icikowski.pl/go/kubeprobes/commit/ec44d7f643e78cfb1e9724b36416458782a6c775))
## [1.3.1-rc.10](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1-rc.9...v1.3.1-rc.10) (2024-05-27)
### Continuous Integrations
* **test:** remove `group` directive ([a1bab99](https://git.ext.icikowski.pl/go/kubeprobes/commit/a1bab99cbdbf903256be3172036fc9b8c44f9992))
## [1.3.1-rc.9](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1-rc.8...v1.3.1-rc.9) (2024-05-21)
### Continuous Integrations
* **deps:** pin `conventional-changelog-conventionalcommits` to version 7.x ([b15846a](https://git.ext.icikowski.pl/go/kubeprobes/commit/b15846aa58864f5809e2226cad9c52770f84aae9))
### Build system and dependencies
* **deps:** update all non-major dependencies ([a68663c](https://git.ext.icikowski.pl/go/kubeprobes/commit/a68663cff022fa135d48fae6f00e39ea684983f1))
* **deps:** update dependency conventional-changelog-conventionalcommits to v8 ([8918072](https://git.ext.icikowski.pl/go/kubeprobes/commit/8918072d5c818bad10542957b93440730d50baf1))
## [1.3.1-rc.8](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1-rc.7...v1.3.1-rc.8) (2024-04-12)
### Build system and dependencies
* **deps:** update dependency semantic-release to v23.0.8 ([b98f6ef](https://git.ext.icikowski.pl/go/kubeprobes/commit/b98f6ef609c278bfbd25c25316ad166fba75f255))
## [1.3.1-rc.7](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1-rc.6...v1.3.1-rc.7) (2024-04-12)
### Build system and dependencies
* **deps:** update dependency @semantic-release/release-notes-generator to v13 ([0cba4d2](https://git.ext.icikowski.pl/go/kubeprobes/commit/0cba4d2a50319cc0250dc3cb14e32dee813b4fc0))
## [1.3.1-rc.6](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1-rc.5...v1.3.1-rc.6) (2024-03-23)
### Build system and dependencies
* **deps:** update dependency semantic-release to v23.0.5 ([061100e](https://git.ext.icikowski.pl/go/kubeprobes/commit/061100e432a61ed6bcb310de297880db369e2f24))
## [1.3.1-rc.5](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1-rc.4...v1.3.1-rc.5) (2024-03-23)
### Build system and dependencies
* **deps:** update dependency @semantic-release/commit-analyzer to v12 ([2a79a68](https://git.ext.icikowski.pl/go/kubeprobes/commit/2a79a6878f647049ca2f01711d74561f6c4974c6))
## [1.3.1-rc.4](https://git.ext.icikowski.pl/go/kubeprobes/compare/v1.3.1-rc.3...v1.3.1-rc.4) (2024-03-17)

View File

@ -1,5 +1,7 @@
# kubeprobes
[![Go Report Card](https://goreportcard.com/badge/pkg.icikowski.pl/kubeprobes)](https://goreportcard.com/report/pkg.icikowski.pl/kubeprobes)
Simple and effective package for implementing [Kubernetes liveness and readiness probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/)' handler.
## Installation
@ -108,8 +110,8 @@ appProbe := func() error {
}
// Create manual probes
live := kubeprobes.NewManualProbe()
ready := kubeprobes.NewManualProbe()
live := kubeprobes.NewManualProbe("liveness")
ready := kubeprobes.NewManualProbe("readiness")
// Prepare handler
kp, err := kubeprobes.New(

View File

@ -1,147 +1,147 @@
package kubeprobes
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"
)
// Kubeprobes represents liveness & readiness probes handler.
type Kubeprobes interface {
http.Handler
// LivenessHandler returns [http.Handler] for liveness probes.
LivenessHandler() http.Handler
// ReadinessHandler returns [http.Handler] for readiness probes.
ReadinessHandler() http.Handler
}
type kubeprobes struct {
livenessProbes []Probe
readinessProbes []Probe
verbose bool
pathLive string
pathReady string
}
// New returns a new instance of a Kubernetes probes with given options.
func New(options ...Option) (Kubeprobes, error) {
kp := &kubeprobes{
livenessProbes: []Probe{},
readinessProbes: []Probe{},
pathLive: defaultLivenessPath,
pathReady: defaultReadinessPath,
}
for _, option := range options {
option.apply(kp)
}
if err := kp.validate(); err != nil {
return nil, err
}
return kp, nil
}
func (kp *kubeprobes) validate() error {
var err error
if kp.pathLive == "" {
err = errors.Join(err, fmt.Errorf("liveness probe path must not be empty"))
}
if kp.pathReady == "" {
err = errors.Join(err, fmt.Errorf("readiness probe path must not be empty"))
}
if !strings.HasPrefix(kp.pathLive, "/") {
err = errors.Join(err, fmt.Errorf("liveness probe path must start with slash (current: %q)", kp.pathLive))
}
if !strings.HasPrefix(kp.pathReady, "/") {
err = errors.Join(err, fmt.Errorf("readiness probe path must start with slash (current: %q)", kp.pathReady))
}
if kp.pathLive == kp.pathReady {
err = errors.Join(err, fmt.Errorf("liveness and readiness probes have the same values (both %q)", kp.pathLive))
}
if len(kp.livenessProbes) == 0 {
err = errors.Join(err, fmt.Errorf("no liveness probes defined"))
}
if len(kp.readinessProbes) == 0 {
err = errors.Join(err, fmt.Errorf("no readiness probes defined"))
}
return err
}
type probesResponse struct {
Passed []statusEntry `json:"passed,omitempty"`
Failed []statusEntry `json:"failed,omitempty"`
}
func (kp *kubeprobes) handleLiveness(w http.ResponseWriter, r *http.Request) {
sq := newStatusQuery(kp.livenessProbes)
output := probesResponse{}
sq.wait()
output.Failed = sq.failed
if r.URL.Query().Has(verboseOutputFlag) || kp.verbose {
output.Passed = sq.passed
}
w.Header().Add(headerContentType, contentTypeJSON)
if sq.ok {
w.WriteHeader(http.StatusOK)
} else {
w.WriteHeader(http.StatusServiceUnavailable)
}
_ = json.NewEncoder(w).Encode(output)
}
func (kp *kubeprobes) handleReadiness(w http.ResponseWriter, r *http.Request) {
sq := newStatusQuery(append(kp.livenessProbes, kp.readinessProbes...))
output := probesResponse{}
sq.wait()
output.Failed = sq.failed
if r.URL.Query().Has(verboseOutputFlag) || kp.verbose {
output.Passed = sq.passed
}
w.Header().Add(headerContentType, contentTypeJSON)
if sq.ok {
w.WriteHeader(http.StatusOK)
} else {
w.WriteHeader(http.StatusServiceUnavailable)
}
_ = json.NewEncoder(w).Encode(output)
}
// LivenessHandler implements Kubeprobes.
func (kp *kubeprobes) LivenessHandler() http.Handler {
return http.HandlerFunc(kp.handleLiveness)
}
// ReadinessHandler implements Kubeprobes.
func (kp *kubeprobes) ReadinessHandler() http.Handler {
return http.HandlerFunc(kp.handleReadiness)
}
// ServeHTTP implements Kubeprobes.
func (kp *kubeprobes) ServeHTTP(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case kp.pathLive:
kp.handleLiveness(w, r)
case kp.pathReady:
kp.handleReadiness(w, r)
default:
w.WriteHeader(http.StatusNotFound)
}
}
package kubeprobes
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"
)
// Kubeprobes represents liveness & readiness probes handler.
type Kubeprobes interface {
http.Handler
// LivenessHandler returns [http.Handler] for liveness probes.
LivenessHandler() http.Handler
// ReadinessHandler returns [http.Handler] for readiness probes.
ReadinessHandler() http.Handler
}
type kubeprobes struct {
livenessProbes []Probe
readinessProbes []Probe
verbose bool
pathLive string
pathReady string
}
// New returns a new instance of a Kubernetes probes with given options.
func New(options ...Option) (Kubeprobes, error) {
kp := &kubeprobes{
livenessProbes: []Probe{},
readinessProbes: []Probe{},
pathLive: defaultLivenessPath,
pathReady: defaultReadinessPath,
}
for _, option := range options {
option.apply(kp)
}
if err := kp.validate(); err != nil {
return nil, err
}
return kp, nil
}
func (kp *kubeprobes) validate() error {
var err error
if kp.pathLive == "" {
err = errors.Join(err, fmt.Errorf("liveness probe path must not be empty"))
}
if kp.pathReady == "" {
err = errors.Join(err, fmt.Errorf("readiness probe path must not be empty"))
}
if !strings.HasPrefix(kp.pathLive, "/") {
err = errors.Join(err, fmt.Errorf("liveness probe path must start with slash (current: %q)", kp.pathLive))
}
if !strings.HasPrefix(kp.pathReady, "/") {
err = errors.Join(err, fmt.Errorf("readiness probe path must start with slash (current: %q)", kp.pathReady))
}
if kp.pathLive == kp.pathReady {
err = errors.Join(err, fmt.Errorf("liveness and readiness probes have the same values (both %q)", kp.pathLive))
}
if len(kp.livenessProbes) == 0 {
err = errors.Join(err, fmt.Errorf("no liveness probes defined"))
}
if len(kp.readinessProbes) == 0 {
err = errors.Join(err, fmt.Errorf("no readiness probes defined"))
}
return err
}
type probesResponse struct {
Passed []statusEntry `json:"passed,omitempty"`
Failed []statusEntry `json:"failed,omitempty"`
}
func (kp *kubeprobes) handleLiveness(w http.ResponseWriter, r *http.Request) {
sq := newStatusQuery(kp.livenessProbes)
output := probesResponse{}
sq.wait()
output.Failed = sq.failed
if r.URL.Query().Has(verboseOutputFlag) || kp.verbose {
output.Passed = sq.passed
}
w.Header().Add(headerContentType, contentTypeJSON)
if sq.ok {
w.WriteHeader(http.StatusOK)
} else {
w.WriteHeader(http.StatusServiceUnavailable)
}
_ = json.NewEncoder(w).Encode(output)
}
func (kp *kubeprobes) handleReadiness(w http.ResponseWriter, r *http.Request) {
sq := newStatusQuery(append(kp.livenessProbes, kp.readinessProbes...))
output := probesResponse{}
sq.wait()
output.Failed = sq.failed
if r.URL.Query().Has(verboseOutputFlag) || kp.verbose {
output.Passed = sq.passed
}
w.Header().Add(headerContentType, contentTypeJSON)
if sq.ok {
w.WriteHeader(http.StatusOK)
} else {
w.WriteHeader(http.StatusServiceUnavailable)
}
_ = json.NewEncoder(w).Encode(output)
}
// LivenessHandler implements Kubeprobes.
func (kp *kubeprobes) LivenessHandler() http.Handler {
return http.HandlerFunc(kp.handleLiveness)
}
// ReadinessHandler implements Kubeprobes.
func (kp *kubeprobes) ReadinessHandler() http.Handler {
return http.HandlerFunc(kp.handleReadiness)
}
// ServeHTTP implements Kubeprobes.
func (kp *kubeprobes) ServeHTTP(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case kp.pathLive:
kp.handleLiveness(w, r)
case kp.pathReady:
kp.handleReadiness(w, r)
default:
w.WriteHeader(http.StatusNotFound)
}
}

View File

@ -1,182 +1,182 @@
package kubeprobes
import (
"net/http"
"net/http/httptest"
"testing"
)
func getStatusFromEndpoint(t *testing.T, client *http.Client, endpoint string) int {
t.Helper()
resp, err := client.Get(endpoint)
if err != nil {
t.Errorf("error getting status from endpoint: %s", err)
}
return resp.StatusCode
}
func TestValidation(t *testing.T) {
var (
live, _ = NewManualProbe("live")
ready, _ = NewManualProbe("ready")
)
tests := map[string]struct {
opts []Option
expectedError bool
}{
"no modifications and no error": {
opts: []Option{
WithLivenessProbes(live),
WithReadinessProbes(ready),
},
},
"modifications and no error": {
opts: []Option{
WithLivenessProbes(live),
WithReadinessProbes(ready),
WithLivenessPath("/livez"),
WithReadinessPath("/readyz"),
},
},
"missing liveness probes": {
opts: []Option{
WithReadinessProbes(ready),
},
expectedError: true,
},
"missing readiness probes": {
opts: []Option{
WithLivenessProbes(live),
},
expectedError: true,
},
"liveness probe path empty": {
opts: []Option{
WithLivenessProbes(live),
WithReadinessProbes(ready),
WithLivenessPath(""),
},
expectedError: true,
},
"readiness probe path empty": {
opts: []Option{
WithLivenessProbes(live),
WithReadinessProbes(ready),
WithReadinessPath(""),
},
expectedError: true,
},
"liveness probe path does not start with slash": {
opts: []Option{
WithLivenessProbes(live),
WithReadinessProbes(ready),
WithLivenessPath("livez"),
},
expectedError: true,
},
"readiness probe path does not start with slash": {
opts: []Option{
WithLivenessProbes(live),
WithReadinessProbes(ready),
WithReadinessPath("readyz"),
},
expectedError: true,
},
"liveness and readiness probe paths are equal": {
opts: []Option{
WithLivenessProbes(live),
WithReadinessProbes(ready),
WithLivenessPath("/check"),
WithReadinessPath("/check"),
},
expectedError: true,
},
}
for name, tc := range tests {
name, tc := name, tc
t.Run(name, func(t *testing.T) {
_, err := New(tc.opts...)
switch {
case err == nil && tc.expectedError:
t.Error("expected error, but no error was returned")
case err != nil && !tc.expectedError:
t.Errorf("expected no error but got %v", err)
}
})
}
}
func TestHandler(t *testing.T) {
var (
live, _ = NewManualProbe("live")
ready, _ = NewManualProbe("ready")
)
tests := map[string]struct {
livenessProbeTransformation func(*testing.T, ManualProbe)
readinessProbeTransformation func(*testing.T, ManualProbe)
expectedLiveStatus int
expectedReadyStatus int
}{
"not live": {
livenessProbeTransformation: markAsDown,
readinessProbeTransformation: markAsDown,
expectedLiveStatus: http.StatusServiceUnavailable,
expectedReadyStatus: http.StatusServiceUnavailable,
},
"live but not ready": {
livenessProbeTransformation: markAsUp,
readinessProbeTransformation: markAsDown,
expectedLiveStatus: http.StatusOK,
expectedReadyStatus: http.StatusServiceUnavailable,
},
"live and ready": {
livenessProbeTransformation: markAsUp,
readinessProbeTransformation: markAsUp,
expectedLiveStatus: http.StatusOK,
expectedReadyStatus: http.StatusOK,
},
"ready but not live - should never happen": {
livenessProbeTransformation: markAsDown,
readinessProbeTransformation: markAsUp,
expectedLiveStatus: http.StatusServiceUnavailable,
expectedReadyStatus: http.StatusServiceUnavailable,
},
}
kp, err := New(
WithLivenessProbes(live),
WithReadinessProbes(ready),
)
if err != nil {
t.Errorf("expected no error, got %v", err)
}
srv := httptest.NewServer(kp)
defer srv.Close()
client := srv.Client()
for name, test := range tests {
name, test := name, test
t.Run(name, func(t *testing.T) {
test.livenessProbeTransformation(t, live)
test.readinessProbeTransformation(t, ready)
liveStatus := getStatusFromEndpoint(t, client, srv.URL+defaultLivenessPath)
readyStatus := getStatusFromEndpoint(t, client, srv.URL+defaultReadinessPath)
otherStatus := getStatusFromEndpoint(t, client, srv.URL+"/something")
if liveStatus != test.expectedLiveStatus {
t.Errorf("expected live status %d, got %d", test.expectedLiveStatus, liveStatus)
}
if readyStatus != test.expectedReadyStatus {
t.Errorf("expected ready status %d, got %d", test.expectedReadyStatus, readyStatus)
}
if otherStatus != http.StatusNotFound {
t.Errorf("expected 404 status, got %d", otherStatus)
}
})
}
}
package kubeprobes
import (
"net/http"
"net/http/httptest"
"testing"
)
func getStatusFromEndpoint(t *testing.T, client *http.Client, endpoint string) int {
t.Helper()
resp, err := client.Get(endpoint)
if err != nil {
t.Errorf("error getting status from endpoint: %s", err)
}
return resp.StatusCode
}
func TestValidation(t *testing.T) {
var (
live, _ = NewManualProbe("live")
ready, _ = NewManualProbe("ready")
)
tests := map[string]struct {
opts []Option
expectedError bool
}{
"no modifications and no error": {
opts: []Option{
WithLivenessProbes(live),
WithReadinessProbes(ready),
},
},
"modifications and no error": {
opts: []Option{
WithLivenessProbes(live),
WithReadinessProbes(ready),
WithLivenessPath("/livez"),
WithReadinessPath("/readyz"),
},
},
"missing liveness probes": {
opts: []Option{
WithReadinessProbes(ready),
},
expectedError: true,
},
"missing readiness probes": {
opts: []Option{
WithLivenessProbes(live),
},
expectedError: true,
},
"liveness probe path empty": {
opts: []Option{
WithLivenessProbes(live),
WithReadinessProbes(ready),
WithLivenessPath(""),
},
expectedError: true,
},
"readiness probe path empty": {
opts: []Option{
WithLivenessProbes(live),
WithReadinessProbes(ready),
WithReadinessPath(""),
},
expectedError: true,
},
"liveness probe path does not start with slash": {
opts: []Option{
WithLivenessProbes(live),
WithReadinessProbes(ready),
WithLivenessPath("livez"),
},
expectedError: true,
},
"readiness probe path does not start with slash": {
opts: []Option{
WithLivenessProbes(live),
WithReadinessProbes(ready),
WithReadinessPath("readyz"),
},
expectedError: true,
},
"liveness and readiness probe paths are equal": {
opts: []Option{
WithLivenessProbes(live),
WithReadinessProbes(ready),
WithLivenessPath("/check"),
WithReadinessPath("/check"),
},
expectedError: true,
},
}
for name, tc := range tests {
name, tc := name, tc
t.Run(name, func(t *testing.T) {
_, err := New(tc.opts...)
switch {
case err == nil && tc.expectedError:
t.Error("expected error, but no error was returned")
case err != nil && !tc.expectedError:
t.Errorf("expected no error but got %v", err)
}
})
}
}
func TestHandler(t *testing.T) {
var (
live, _ = NewManualProbe("live")
ready, _ = NewManualProbe("ready")
)
tests := map[string]struct {
livenessProbeTransformation func(*testing.T, ManualProbe)
readinessProbeTransformation func(*testing.T, ManualProbe)
expectedLiveStatus int
expectedReadyStatus int
}{
"not live": {
livenessProbeTransformation: markAsDown,
readinessProbeTransformation: markAsDown,
expectedLiveStatus: http.StatusServiceUnavailable,
expectedReadyStatus: http.StatusServiceUnavailable,
},
"live but not ready": {
livenessProbeTransformation: markAsUp,
readinessProbeTransformation: markAsDown,
expectedLiveStatus: http.StatusOK,
expectedReadyStatus: http.StatusServiceUnavailable,
},
"live and ready": {
livenessProbeTransformation: markAsUp,
readinessProbeTransformation: markAsUp,
expectedLiveStatus: http.StatusOK,
expectedReadyStatus: http.StatusOK,
},
"ready but not live - should never happen": {
livenessProbeTransformation: markAsDown,
readinessProbeTransformation: markAsUp,
expectedLiveStatus: http.StatusServiceUnavailable,
expectedReadyStatus: http.StatusServiceUnavailable,
},
}
kp, err := New(
WithLivenessProbes(live),
WithReadinessProbes(ready),
)
if err != nil {
t.Errorf("expected no error, got %v", err)
}
srv := httptest.NewServer(kp)
defer srv.Close()
client := srv.Client()
for name, test := range tests {
name, test := name, test
t.Run(name, func(t *testing.T) {
test.livenessProbeTransformation(t, live)
test.readinessProbeTransformation(t, ready)
liveStatus := getStatusFromEndpoint(t, client, srv.URL+defaultLivenessPath)
readyStatus := getStatusFromEndpoint(t, client, srv.URL+defaultReadinessPath)
otherStatus := getStatusFromEndpoint(t, client, srv.URL+"/something")
if liveStatus != test.expectedLiveStatus {
t.Errorf("expected live status %d, got %d", test.expectedLiveStatus, liveStatus)
}
if readyStatus != test.expectedReadyStatus {
t.Errorf("expected ready status %d, got %d", test.expectedReadyStatus, readyStatus)
}
if otherStatus != http.StatusNotFound {
t.Errorf("expected 404 status, got %d", otherStatus)
}
})
}
}

2744
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,18 @@
{
"private": true,
"name": "kubeprobes",
"version": "1.3.1-rc.4",
"version": "1.3.2-rc.3",
"scripts": {
"release": "./node_modules/.bin/semantic-release"
},
"devDependencies": {
"@saithodev/semantic-release-gitea": "^2.1.0",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/commit-analyzer": "^11.0.0",
"@semantic-release/commit-analyzer": "^13.0.0",
"@semantic-release/git": "^10.0.1",
"@semantic-release/npm": "^12.0.0",
"@semantic-release/release-notes-generator": "^12.0.1",
"conventional-changelog-conventionalcommits": "^7.0.2",
"semantic-release": "^23.0.0"
"@semantic-release/release-notes-generator": "^14.0.0",
"conventional-changelog-conventionalcommits": "^8.0.0",
"semantic-release": "^24.0.0"
}
}