1
0
Fork 0
mirror of https://github.com/eosswedenorg/antelope-api-healthcheck synced 2026-07-03 11:53:43 +02:00

Compare commits

...

388 commits

Author SHA1 Message Date
77f3fbde85 remove .github/dependabot.yml 2025-04-29 06:12:06 +02:00
efa0e71f03 Merge branch 'dev' 2025-04-29 06:05:23 +02:00
d37e4c28e7
Merge pull request #25 from eosswedenorg/dependabot/go_modules/golang.org/x/net-0.23.0
build(deps): bump golang.org/x/net from 0.17.0 to 0.23.0
2025-04-29 05:23:42 +02:00
e331b9e2e5
Merge pull request #29 from eosswedenorg/dependabot/go_modules/dev/github.com/panjf2000/gnet/v2-2.5.3
build(deps): bump github.com/panjf2000/gnet/v2 from 2.3.5 to 2.5.3
2025-04-29 05:23:13 +02:00
dependabot[bot]
067aa54095
build(deps): bump github.com/panjf2000/gnet/v2 from 2.3.5 to 2.5.3
Bumps [github.com/panjf2000/gnet/v2](https://github.com/panjf2000/gnet) from 2.3.5 to 2.5.3.
- [Release notes](https://github.com/panjf2000/gnet/releases)
- [Commits](https://github.com/panjf2000/gnet/compare/v2.3.5...v2.5.3)

---
updated-dependencies:
- dependency-name: github.com/panjf2000/gnet/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-04 08:56:38 +00:00
dependabot[bot]
e2d6f8f2cd
build(deps): bump golang.org/x/net from 0.17.0 to 0.23.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.17.0 to 0.23.0.
- [Commits](https://github.com/golang/net/compare/v0.17.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-19 12:31:09 +00:00
bc5e9c13eb
Merge pull request #19 from eosswedenorg/dependabot/go_modules/dev/github.com/panjf2000/gnet/v2-2.3.5
build(deps): bump github.com/panjf2000/gnet/v2 from 2.3.4 to 2.3.5
2024-03-07 21:48:05 +01:00
8e45579eb9
Merge pull request #20 from eosswedenorg/dependabot/go_modules/dev/github.com/stretchr/testify-1.9.0
build(deps): bump github.com/stretchr/testify from 1.8.4 to 1.9.0
2024-03-07 21:47:57 +01:00
dependabot[bot]
c008a3ec1e
build(deps): bump github.com/stretchr/testify from 1.8.4 to 1.9.0
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.4 to 1.9.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.4...v1.9.0)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-05 08:05:48 +00:00
dependabot[bot]
40fb0349ed
build(deps): bump github.com/panjf2000/gnet/v2 from 2.3.4 to 2.3.5
Bumps [github.com/panjf2000/gnet/v2](https://github.com/panjf2000/gnet) from 2.3.4 to 2.3.5.
- [Release notes](https://github.com/panjf2000/gnet/releases)
- [Commits](https://github.com/panjf2000/gnet/compare/v2.3.4...v2.3.5)

---
updated-dependencies:
- dependency-name: github.com/panjf2000/gnet/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-05 08:05:37 +00:00
5ef28b0a06
Merge pull request #17 from eosswedenorg/dependabot/go_modules/dev/github.com/panjf2000/gnet/v2-2.3.4
build(deps): bump github.com/panjf2000/gnet/v2 from 2.3.3 to 2.3.4
2024-01-10 16:27:28 +01:00
dependabot[bot]
65d3359f1b
build(deps): bump github.com/panjf2000/gnet/v2 from 2.3.3 to 2.3.4
Bumps [github.com/panjf2000/gnet/v2](https://github.com/panjf2000/gnet) from 2.3.3 to 2.3.4.
- [Release notes](https://github.com/panjf2000/gnet/releases)
- [Commits](https://github.com/panjf2000/gnet/compare/v2.3.3...v2.3.4)

---
updated-dependencies:
- dependency-name: github.com/panjf2000/gnet/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-09 08:17:45 +00:00
79e53ff89e
Merge pull request #16 from eosswedenorg/dependabot/go_modules/golang.org/x/crypto-0.17.0
build(deps): bump golang.org/x/crypto from 0.4.0 to 0.17.0
2023-12-19 12:55:53 +01:00
dependabot[bot]
ee40a7066c
build(deps): bump golang.org/x/crypto from 0.4.0 to 0.17.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.4.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.4.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-19 11:54:56 +00:00
84888c7bed
Merge pull request #15 from eosswedenorg/dependabot/go_modules/golang.org/x/net-0.17.0
build(deps): bump golang.org/x/net from 0.7.0 to 0.17.0
2023-12-19 12:53:42 +01:00
dependabot[bot]
5e73f6799f
build(deps): bump golang.org/x/net from 0.7.0 to 0.17.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.7.0 to 0.17.0.
- [Commits](https://github.com/golang/net/compare/v0.7.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-11 23:27:06 +00:00
fa9e87a90f
Merge pull request #14 from eosswedenorg/dependabot/go_modules/dev/github.com/panjf2000/gnet/v2-2.3.3
build(deps): bump github.com/panjf2000/gnet/v2 from 2.3.2 to 2.3.3
2023-09-20 14:49:54 +02:00
dependabot[bot]
828e38797a
build(deps): bump github.com/panjf2000/gnet/v2 from 2.3.2 to 2.3.3
Bumps [github.com/panjf2000/gnet/v2](https://github.com/panjf2000/gnet) from 2.3.2 to 2.3.3.
- [Release notes](https://github.com/panjf2000/gnet/releases)
- [Commits](https://github.com/panjf2000/gnet/compare/v2.3.2...v2.3.3)

---
updated-dependencies:
- dependency-name: github.com/panjf2000/gnet/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-19 08:14:04 +00:00
8a0ab6bb7b
Merge pull request #13 from eosswedenorg/dependabot/go_modules/dev/github.com/panjf2000/gnet/v2-2.3.2
build(deps): bump github.com/panjf2000/gnet/v2 from 2.3.1 to 2.3.2
2023-09-13 04:31:24 +00:00
dependabot[bot]
65fd7cff9c
build(deps): bump github.com/panjf2000/gnet/v2 from 2.3.1 to 2.3.2
Bumps [github.com/panjf2000/gnet/v2](https://github.com/panjf2000/gnet) from 2.3.1 to 2.3.2.
- [Release notes](https://github.com/panjf2000/gnet/releases)
- [Commits](https://github.com/panjf2000/gnet/compare/v2.3.1...v2.3.2)

---
updated-dependencies:
- dependency-name: github.com/panjf2000/gnet/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 08:55:43 +00:00
a024913244
Adding internal/api/make_test.go 2023-08-24 19:35:13 +02:00
b98164116e
Makefile: Indent fixes. 2023-08-15 09:46:03 +02:00
4e56ee60fc
README.md: minor fixes. 2023-08-15 09:45:42 +02:00
eaeec1645d
Version 1.4.6 2023-07-25 17:31:03 +02:00
e461d20125
Merge pull request #12 from eosswedenorg/dependabot/go_modules/dev/github.com/panjf2000/gnet/v2-2.3.1
build(deps): bump github.com/panjf2000/gnet/v2 from 2.3.0 to 2.3.1
2023-07-25 17:27:33 +02:00
dependabot[bot]
18a3a8a3d5
build(deps): bump github.com/panjf2000/gnet/v2 from 2.3.0 to 2.3.1
Bumps [github.com/panjf2000/gnet/v2](https://github.com/panjf2000/gnet) from 2.3.0 to 2.3.1.
- [Release notes](https://github.com/panjf2000/gnet/releases)
- [Commits](https://github.com/panjf2000/gnet/compare/v2.3.0...v2.3.1)

---
updated-dependencies:
- dependency-name: github.com/panjf2000/gnet/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-25 08:19:32 +00:00
61724eb8d2
Merge pull request #11 from eosswedenorg/dependabot/go_modules/dev/github.com/panjf2000/gnet/v2-2.3.0
build(deps): bump github.com/panjf2000/gnet/v2 from 2.2.9 to 2.3.0
2023-07-05 04:49:35 +02:00
dependabot[bot]
6fe3d2572a
build(deps): bump github.com/panjf2000/gnet/v2 from 2.2.9 to 2.3.0
Bumps [github.com/panjf2000/gnet/v2](https://github.com/panjf2000/gnet) from 2.2.9 to 2.3.0.
- [Release notes](https://github.com/panjf2000/gnet/releases)
- [Commits](https://github.com/panjf2000/gnet/compare/v2.2.9...v2.3.0)

---
updated-dependencies:
- dependency-name: github.com/panjf2000/gnet/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-04 08:20:18 +00:00
9eda495d4e
Merge pull request #10 from eosswedenorg/dependabot/go_modules/dev/github.com/stretchr/testify-1.8.4
build(deps): bump github.com/stretchr/testify from 1.8.3 to 1.8.4
2023-06-07 10:25:18 +02:00
dependabot[bot]
75b8a7bab1
build(deps): bump github.com/stretchr/testify from 1.8.3 to 1.8.4
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.3 to 1.8.4.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.3...v1.8.4)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-06 08:57:16 +00:00
3b497afd76
debian/copyright: update year 2023-05-24 13:05:55 +02:00
dd76ae2b19
Version 1.4.5 2023-05-23 17:23:25 +02:00
d253128d6d
Merge pull request #9 from eosswedenorg/dependabot/go_modules/dev/github.com/stretchr/testify-1.8.3
build(deps): bump github.com/stretchr/testify from 1.8.2 to 1.8.3
2023-05-23 16:18:25 +02:00
dependabot[bot]
2299331321
build(deps): bump github.com/stretchr/testify from 1.8.2 to 1.8.3
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.2 to 1.8.3.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.2...v1.8.3)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-23 13:47:50 +00:00
232aa7df65
Merge pull request #8 from eosswedenorg/dependabot/go_modules/dev/github.com/panjf2000/gnet/v2-2.2.9
build(deps): bump github.com/panjf2000/gnet/v2 from 2.2.7 to 2.2.9
2023-05-23 15:47:11 +02:00
dependabot[bot]
2d6e768e2a
build(deps): bump github.com/panjf2000/gnet/v2 from 2.2.7 to 2.2.9
Bumps [github.com/panjf2000/gnet/v2](https://github.com/panjf2000/gnet) from 2.2.7 to 2.2.9.
- [Release notes](https://github.com/panjf2000/gnet/releases)
- [Commits](https://github.com/panjf2000/gnet/compare/v2.2.7...v2.2.9)

---
updated-dependencies:
- dependency-name: github.com/panjf2000/gnet/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-23 08:57:17 +00:00
80ba31050e
Merge pull request #7 from eosswedenorg/dependabot/go_modules/dev/github.com/eosswedenorg-go/atomicasset-0.1.2
build(deps): bump github.com/eosswedenorg-go/atomicasset from 0.1.1 to 0.1.2
2023-05-10 07:13:50 +02:00
dependabot[bot]
5dc14716c5
build(deps): bump github.com/eosswedenorg-go/atomicasset
Bumps [github.com/eosswedenorg-go/atomicasset](https://github.com/eosswedenorg-go/atomicasset) from 0.1.1 to 0.1.2.
- [Release notes](https://github.com/eosswedenorg-go/atomicasset/releases)
- [Commits](https://github.com/eosswedenorg-go/atomicasset/compare/v0.1.1...v0.1.2)

---
updated-dependencies:
- dependency-name: github.com/eosswedenorg-go/atomicasset
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-10 05:12:43 +00:00
c8dd655e36
internal/api/atomicasset_test.go: minor style fix. 2023-05-10 07:03:49 +02:00
10f3a4d4be
internal/api/atomicasset_test.go: Bugfix in calls to time.Date(), ment to pass 500 milliseconds, not microseconds. 2023-05-10 07:01:53 +02:00
995f6a8629
Merge pull request #6 from eosswedenorg/dependabot/go_modules/dev/github.com/panjf2000/gnet/v2-2.2.7
build(deps): bump github.com/panjf2000/gnet/v2 from 2.2.6 to 2.2.7
2023-04-19 08:48:54 +02:00
dependabot[bot]
c53cb4fe1f
build(deps): bump github.com/panjf2000/gnet/v2 from 2.2.6 to 2.2.7
Bumps [github.com/panjf2000/gnet/v2](https://github.com/panjf2000/gnet) from 2.2.6 to 2.2.7.
- [Release notes](https://github.com/panjf2000/gnet/releases)
- [Commits](https://github.com/panjf2000/gnet/compare/v2.2.6...v2.2.7)

---
updated-dependencies:
- dependency-name: github.com/panjf2000/gnet/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-18 08:57:24 +00:00
824ae9ca9d
Version 1.4.4 2023-04-04 07:47:16 +02:00
f377538f4c
go.mod: Update github.com/eosswedenorg-go/atomicasset to v0.1.1 2023-04-04 06:54:35 +02:00
92e7b89f81
Merge pull request #5 from eosswedenorg/dependabot/go_modules/golang.org/x/net-0.7.0
build(deps): bump golang.org/x/net from 0.4.0 to 0.7.0
2023-04-04 06:19:18 +02:00
dependabot[bot]
320b54cce8
build(deps): bump golang.org/x/net from 0.4.0 to 0.7.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.4.0 to 0.7.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.4.0...v0.7.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-04 04:13:45 +00:00
9a34d2647d
Version 1.4.3 2023-04-04 06:12:04 +02:00
37c8bbc357
.github/dependabot.yml: Set target branch to dev. 2023-04-04 06:05:55 +02:00
528461ebe4
Merge pull request #4 from eosswedenorg/dependabot/go_modules/github.com/panjf2000/gnet/v2-2.2.6
build(deps): bump github.com/panjf2000/gnet/v2 from 2.2.4 to 2.2.6
2023-04-04 06:02:12 +02:00
ad596c15ad
Merge branch 'dev' into dependabot/go_modules/github.com/panjf2000/gnet/v2-2.2.6 2023-04-04 06:01:25 +02:00
8ef31fc4e7
Merge pull request #3 from eosswedenorg/dependabot/go_modules/github.com/inconshreveable/log15-3.0.0-testing.5incompatible
build(deps): bump github.com/inconshreveable/log15 from 0.0.0-20221122034931-555555054819 to 3.0.0-testing.5+incompatible
2023-04-04 06:00:02 +02:00
b8b61d5064
Merge pull request #2 from eosswedenorg/dependabot/go_modules/github.com/stretchr/testify-1.8.2
build(deps): bump github.com/stretchr/testify from 1.8.1 to 1.8.2
2023-04-04 05:59:00 +02:00
dependabot[bot]
03ec91a675
build(deps): bump github.com/panjf2000/gnet/v2 from 2.2.4 to 2.2.6
Bumps [github.com/panjf2000/gnet/v2](https://github.com/panjf2000/gnet) from 2.2.4 to 2.2.6.
- [Release notes](https://github.com/panjf2000/gnet/releases)
- [Commits](https://github.com/panjf2000/gnet/compare/v2.2.4...v2.2.6)

---
updated-dependencies:
- dependency-name: github.com/panjf2000/gnet/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-04 03:48:15 +00:00
dependabot[bot]
b8b44ecf24
build(deps): bump github.com/inconshreveable/log15
Bumps [github.com/inconshreveable/log15](https://github.com/inconshreveable/log15) from 0.0.0-20221122034931-555555054819 to 3.0.0-testing.5+incompatible.
- [Release notes](https://github.com/inconshreveable/log15/releases)
- [Commits](https://github.com/inconshreveable/log15/commits/v3.0.0-testing.5)

---
updated-dependencies:
- dependency-name: github.com/inconshreveable/log15
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-04 03:48:08 +00:00
dependabot[bot]
df0f8b0c43
build(deps): bump github.com/stretchr/testify from 1.8.1 to 1.8.2
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.1 to 1.8.2.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.1...v1.8.2)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-04 03:48:05 +00:00
7f68732eae
Adding .github/dependabot.yml 2023-04-04 05:44:06 +02:00
6b0776937a
cmd/antelope-api-healtcheck/main.go: Typo fix. 2023-02-15 18:09:20 +01:00
cf2aef149a
Version 1.4.2 2023-02-14 09:35:47 +01:00
4b15a56804
cmd/antelope-api-healtcheck/main.go: Change default timeout to 2 seconds. 2023-02-14 09:10:56 +01:00
8deb0b9bf3
scripts/install_linux.sh: Install syslog-ng config files. 2023-02-14 09:00:03 +01:00
a632ba914f
Adding scripts/templates/syslog-ng.conf 2023-02-14 08:59:32 +01:00
5bf880b0d0
cmd/antelope-api-healtcheck/main.go: exit with status 1 if srv.Run() fails. 2023-02-07 16:42:00 +01:00
318d14f44b
Makefile: use $GO variable when setting GOOS and GOARCH 2023-02-07 16:29:31 +01:00
9814f07612
Version 1.4.0 2023-02-07 12:36:45 +01:00
9b28e45295
cmd/antelope-v1-mock-server/main.go: adding -d flag for random delays. 2023-02-07 12:32:43 +01:00
228d7ae731
cmd/antelope-api-healtcheck/main.go: req_timeout.Minutes() returns a float, so must check for greater than 1.0 instead of 0. 2023-02-07 12:25:03 +01:00
adf9508197
cmd/antelope-api-healtcheck/main.go: srv.Run() does not only return error on server shutdown. so modify the message. 2023-02-07 09:23:37 +01:00
550cabc64b
cmd/antelope-api-healtcheck/main.go: adding -t,--timeout cli flag. 2023-02-07 09:22:15 +01:00
d73187ec38
internal/server/server.go: Make context timeout configurable. 2023-02-07 09:21:10 +01:00
6030981ba5
internal/server/server.go: Implement options using the functional pattern. 2023-02-07 09:11:17 +01:00
6b561bdf25
internal/api/atomicasset_test.go: Add LogInfoWithHost test 2023-02-07 08:43:29 +01:00
0448ea4781
internal/api/atomicasset.go: In LogInfo() add host parameter. 2023-02-07 08:43:02 +01:00
afd79110f9
internal/server/parse_request_test.go: Adding AtomicAssetWithHost test. 2023-02-07 08:38:51 +01:00
59399c7cf4
internal/api/atomicasset.go: Support host parameter. 2023-02-07 08:38:21 +01:00
f0ab79ef06
internal/api/atomicasset.go: Pass context to atomicasset api. 2023-02-07 08:32:44 +01:00
919599f86d
go mod: Update github.com/eosswedenorg-go/atomicasset to v0.1.1-0.20230206134606-4577244fa67a 2023-02-06 19:02:53 +01:00
d67864dadf
go.mod: Update github.com/eosswedenorg-go/leapapi to v0.2.3 2023-02-06 16:31:44 +01:00
dbf59d1305
internal/api/interface.go: make Call() accept a context as parameter. 2023-02-06 14:21:29 +01:00
b815bcee44
internal/server/server.go: Adding request duration to log row. 2023-02-06 14:15:06 +01:00
12bd16399b
internal/server/server.go: Adding OnClose() 2023-02-06 12:52:13 +01:00
83fd4826d7
internal/server/server.go: need to provide a callback to AsyncWrite to close the connection. 2023-02-06 12:45:50 +01:00
5ed22bfdc6
Makefile add build/antelope-v1-mock-server to .PHONY target 2023-02-06 10:01:11 +01:00
df1476355f
cmd/antelope-api-healtcheck/main.go: Comment fix. 2023-02-02 18:55:39 +01:00
4cdae2d3f1
internal/api/debug.go: no need to return error in parseResponse() as it is always nil. 2023-02-02 18:52:36 +01:00
aff3737f67
internal/server/parse_request.go: remove weird comment 2023-02-02 18:51:44 +01:00
9456b8acbb
cmd/antelope-api-healtcheck/main.go: in signalEventLoop() no need to wrap the for loop in a anonymous function. 2023-02-02 18:19:53 +01:00
fba9402584
cmd/antelope-api-healtcheck/main.go: Minor fix. 2023-02-02 18:18:49 +01:00
755438408b
go.mod: Update github.com/panjf2000/gnet/v2 to v2.2.4 2023-01-19 13:01:13 +01:00
a811f82028
go.mod: update github.com/eosswedenorg-go/gnet/v2@v2.2.2-kqueue-fix to github.com/panjf2000/gnet/v2@v2.2.3-0.20230105151625-72b6e726ce32
This commit fixes the kqueue 32-bit bug in upstream.
2023-01-19 12:56:29 +01:00
46fe9b3e47
.github/workflows/test.yml: Also cross-compile to make sure it builds on everything. 2023-01-05 14:29:32 +01:00
b9b1e71bcd
go mod: replace github.com/panjf2000/gnet/v2 v2.2.2 with github.com/eosswedenorg-go/gnet/v2 v2.2.2-kqueue-fix
There is a bug in panjf2000/gnet currently that affects compilation on BSD 32-bit systems. Its temporary fixes in eosswedenorg-go/gnet fork.
2023-01-05 14:26:43 +01:00
1f6811c3b6
.github/workflows/release.yml: Adding fail-fast: false to strategy. 2023-01-05 13:02:31 +01:00
852a17bf9e
.github/workflows/release.yml: Setup go v1.18 2023-01-05 12:48:32 +01:00
32178dd47f
.github/workflows/test.yml: Update actions/checkout and actions/setup-go to v3. 2023-01-05 12:46:45 +01:00
dcf035ec6c
.github/workflows/release.yml: Update actions/checkout to v3 2023-01-05 12:46:15 +01:00
29ed2d790b
Version 1.4.0 2023-01-04 14:09:06 +01:00
62d039deb2
internal/server/server.go: Make OnTick() interval configurable. 2023-01-04 14:02:43 +01:00
a73f1eae8b
internal/server/server.go: Some documentation. 2023-01-04 13:55:07 +01:00
1f22435dfa
internal/server/server.go: count number of connections and send a log message in OnTick() 2023-01-04 13:53:29 +01:00
1db04c0e76
replace github.com/eosswedenorg-go/tcp_server with github.com/panjf2000/gnet 2023-01-03 17:45:56 +01:00
be7a246317
Makefile: adding "test-utils" target. 2023-01-02 19:12:56 +01:00
d365b5deb1
Adding cmd/antelope-v1-mock-server/main.go 2023-01-02 19:12:33 +01:00
a6b0575cf7
LICENSE: Update copyright year. 2023-01-02 12:56:04 +01:00
28d4ab3437
go.mod: Update github.com/eosswedenorg-go/leapapi to v0.2.2 2023-01-02 12:55:33 +01:00
d752839f0b
go.sum: cleanup old packages. 2023-01-02 12:54:09 +01:00
86e87d8245
internal/api: rename eosio_*.go to antelope_*.go 2022-12-22 14:17:22 +01:00
1fc8c927aa
go mod: Upgrade indirect packages. 2022-12-22 12:46:09 +01:00
2caad14e44
go mod: Update github.com/eosswedenorg-go/haproxy to v1.0.1 2022-12-22 12:41:26 +01:00
64d46ed460
go mod: Update github.com/eosswedenorg-go/atomicasset to v0.1.0 2022-12-22 12:04:31 +01:00
142465ac16
Version 1.3.1 2022-12-12 16:24:48 +01:00
4f77e23797
go mod: upgrade github.com/eosswedenorg-go/leapapi to v0.2.1 2022-12-12 15:06:08 +01:00
c19dc9a63b
README.md: Adding cool badges. 2022-12-09 13:08:00 +01:00
f0db33f9b1
Require a minimum go version of 1.18 2022-12-06 15:21:38 +01:00
a771b25415
Version 1.3.0 2022-11-25 12:41:31 +01:00
22b10006d7
go.sum: Remove old packages. 2022-11-25 12:39:51 +01:00
005ad9fcd0
go mod: change github.com/eosswedenorg-go/eosapi v0.1.3 to github.com/eosswedenorg-go/leapapi v0.2.0 2022-11-25 12:39:51 +01:00
61cb49f8be
Rename project from eosio-api-healthcheck to antelope-api-healthcheck 2022-11-25 12:39:51 +01:00
e0a7a10662
README.md: Update documentation to reflect the name change from contract to atomic. 2022-11-25 10:24:43 +01:00
881e7cd760
internal/server/parse_request_test.go: Remove out commented import. 2022-11-24 15:06:58 +01:00
9109bef803
internal/api/make.go: remove "contract" api in favor for the new "atomic" name. 2022-11-24 15:06:02 +01:00
0f5fdedd91
Version 1.2.6 2022-11-24 15:04:10 +01:00
c89da02738
Cleanup test names. 2022-11-24 14:56:22 +01:00
d2b8e7d0dc
internal/api/eosio_v2_test.go: Assert any errors from http.ResponseWriter.Write() 2022-11-24 14:51:17 +01:00
bcd9a93a35
internal/api/eosio_v1_test.go: Assert any errors from http.ResponseWriter.Write() 2022-11-24 14:51:17 +01:00
c48162742f
internal/api/atomicasset_test.go: Assert any errors from http.ResponseWriter.Write() 2022-11-24 14:45:46 +01:00
a768d89909
cmd/eosio-api-healtcheck/main.go: store server object returned from server.Start() and call Close() after event loop. 2022-11-24 14:39:03 +01:00
2daa5801c1
internal/server/server.go: Make Start() return an tcp_server.Server object. 2022-11-24 14:37:57 +01:00
34814dae05
go: upgrade github.com/eosswedenorg-go/tcp_server to v0.2.1 2022-11-24 14:37:10 +01:00
72bdde0457
internal/server/server.go: in Start() no need to spawn server.Listen() in a go routine as that function is already non-blocking. 2022-11-23 17:22:44 +01:00
8feca959d4
internal/server/parse_request.go: move api factory code into its own function in api package: api.Make() 2022-11-23 17:14:51 +01:00
1fb48800a1
internal/server/parse_request.go: Add AtomicAsset in factories with "atomic" as key. 2022-11-23 17:07:39 +01:00
2b0b32b5ab
rename EosioContract to AtomicAsset. 2022-11-23 17:04:54 +01:00
1b1f601678
move internal/*.go files into internal/server 2022-11-23 16:54:22 +01:00
e9976fbbee
Change github.com/eosswedenorg-go/eos-contract-api-client to github.com/eosswedenorg-go/atomicasset 2022-11-23 16:04:23 +01:00
bcc704c4c0
internal/server.go: in onTcpMessage() check error return value of c.WriteString() 2022-11-23 15:56:59 +01:00
adb1ad3c6d
Fix code formatting 2022-11-23 15:53:26 +01:00
b0e5b455ca
go: update github.com/inconshreveable/log15 to v0.0.0-20221122034931-555555054819 2022-11-22 10:10:00 +01:00
b09e5ba463
go: update github.com/eosswedenorg-go/eosapi to v0.1.3 2022-11-22 10:08:47 +01:00
a17e2929e3
internal/api/eosio_v1.go: HTTP Errors are now handled in eosapi. This changes the log message abit and return haproxy status from "Down" to "Fail" 2022-11-18 15:40:55 +01:00
9102240837
internal/api/eosio_v2.go: HTTP Errors are now handled in the eosapi. This changes the log message abit and return haproxy status from "Down" to "Fail" 2022-11-18 15:40:55 +01:00
0b463e5111
go.mod: Update github.com/eosswedenorg-go/eosapi to v0.1.2 2022-11-18 15:37:41 +01:00
d8d872adae
go.mod: update github.com/stretchr/testify to v1.8.1 2022-10-27 12:58:56 +02:00
6448aeb0f7
Refactor: move internal package from src/ to internal/ and move src/main.go to cmd/eosio-api-healthcheck/main.go 2022-10-27 12:58:30 +02:00
c27abb5ed9
.gitignore: ignore .vscode directory 2022-10-26 14:27:17 +02:00
cb8eec6ff6
Merge branch 'api-refactor' into dev 2022-10-26 10:31:42 +02:00
c168e263df
src/server.go: in onTcpMessage() cleanup logging calls using api.LogParams Add and Combine functions. 2022-10-26 10:29:25 +02:00
15ff583035
src/parse_request.go: in ParseRequest() change switch case into a map with factory functions. 2022-10-25 17:49:22 +02:00
b41fb21f6a
src/parse_request.go: use api.ApiArguments instead of arguments struct 2022-10-25 17:46:32 +02:00
d8c8c14edc
src/api/eosio_contract.go: Adding EosioContractFactory function 2022-10-25 17:43:16 +02:00
9fcffe375a
src/api/eosio_v2.go: Adding EosioV2Factory function 2022-10-25 17:42:46 +02:00
7b78d2632b
src/api/eosio_v1.go: Adding EosioV1Factory function 2022-10-25 17:42:30 +02:00
39927a2441
src/api/debug.go: Adding DebugApiFactory function 2022-10-25 17:31:36 +02:00
6e8ffe718e
src/api/interface.go: Adding Factory function type. 2022-10-25 17:22:33 +02:00
0081f86f0d
src/api/interface.go: Adding ApiArguments struct. 2022-10-25 17:21:56 +02:00
8079962be8
src/api/log_params.go: Adding Combine() 2022-10-21 15:08:33 +02:00
8d2c1c8fa3
src/api/log_params.go: Don't need a ToSlice() function as LogParams is already a slice. 2022-10-21 15:08:00 +02:00
3ab2db7cb3
src/api/log_params_test.go: change assert.Equal() to assert.ElementsMatch() to ignore slice order. 2022-10-21 14:29:02 +02:00
7f387680ec
Version 1.2.5 2022-10-21 13:43:09 +02:00
aa98134a1e
src/utils/json_test.go: refactor test functions into a single one. 2022-10-21 13:19:34 +02:00
3568e7c908
src/utils/parse_log_formatter_test.go: fix whitespace. 2022-10-21 13:14:23 +02:00
818cf7e7e5
move src/helpers.go to src/utils/parse_log_formatter.go 2022-10-21 13:13:02 +02:00
97d9e662ce
scripts/templates/config: Add "--log-format=logfmt" to default options. 2022-10-21 12:43:37 +02:00
76e50d1801
install linux: change config file from /etc/defualts/ to /etc/sysconfig 2022-10-21 12:39:39 +02:00
311d9b34cb
src/main.go: Add cli flag to change logging format. 2022-10-20 15:15:11 +02:00
704965b9cc
Adding src/helpers.go 2022-10-20 15:09:21 +02:00
da28a68943
Version 1.2.4 2022-10-13 14:40:25 +02:00
e36913cc92
README.md: Update documentation to golang v1.16 as the minimum version. 2022-10-13 13:31:13 +02:00
7fe06a144a
.github/workflows/test.yml: rename to test. 2022-10-13 13:04:54 +02:00
822bfaa16e
go: update github.com/eosswedenorg-go/tcp_server to v0.2.0 2022-10-13 12:34:56 +02:00
da87724920
go: update github.com/eosswedenorg-go/eos-contract-api-client 2022-10-13 12:33:01 +02:00
35b81cdcdc
src/api/eosio_contract_test.go: in TestEosioContractHTTP500Down() need to set content-type header. 2022-10-12 18:25:04 +02:00
3e9bf2aa75
Update to go v1.16 2022-10-12 17:19:55 +02:00
f5ff3480e0
go: Update github.com/eosswedenorg-go/eosapi to v0.1.1 2022-10-12 12:25:42 +02:00
8f81047e02
src/parse_request_test.go: compare api's LogInfo() function as comparing the structs directly.
Comparing the structs may failsly error because of internal variables (like pointer) not being equal.
So just compare the data we actually care about, and those is returned by LogInfo().
2022-10-12 12:24:52 +02:00
ce1ad75649
go: Upgrade github.com/mattn/go-colorable to v0.1.13 2022-10-12 11:50:49 +02:00
9558aea0a8
go: Upgrade github.com/eosswedenorg-go/pid to v1.0.1 2022-10-12 11:50:17 +02:00
c2cc60dbfb
Makefile adding coverage target 2022-10-03 16:37:51 +02:00
f77edfe321
src/parse_request.go: linter does not like capitalized error strings. 2022-10-03 16:37:34 +02:00
bc6f857c1e
Adding src/api/debug_test.go 2022-10-03 16:32:17 +02:00
0349999540
src/parse_request_test.go: adding test for debug api. 2022-10-03 16:15:47 +02:00
edb063722b
src/api/test.go: rename from TestApi to DebugApi 2022-10-03 16:15:25 +02:00
bda40bf1d5
src/parse_request_test.go: add test for invalid api type. 2022-10-03 16:13:32 +02:00
11c1e8afcd
Version 1.2.3 2022-08-22 18:19:55 +02:00
566071c997
Makefile: for dpkg-buildpackage skip building source and only build binary package. 2022-08-22 18:19:46 +02:00
ad5830ed34
scripts/install_freebsd.sh: pass description correctly to rc.conf 2022-08-22 17:44:37 +02:00
0f4f4ad994
scripts/templates/rc.conf: prefix DESCRIPTION 2022-08-22 17:44:37 +02:00
d0d32ed740
scripts/install_linux.sh: Pass description correctly to sysunit service file. 2022-08-22 17:44:36 +02:00
6de7ca549f
scripts/templates/sysunit.service: prefix DESCRIPTION variable. 2022-08-22 17:44:36 +02:00
22255b9758
.github/workflows/release.yml: Remove ubuntu-18.04 as github will drop support on 2022-12-01 2022-08-22 17:44:33 +02:00
843d30bb3d
set-version.sh: handle spaces for Makefile variable. 2022-08-22 15:43:13 +02:00
c94f274da3
debian/changelog: Update v1.2.3 with a real changelog. 2022-08-22 14:19:30 +02:00
47077aa84c
.github/workflows/release.yml: Update to work with the new buildsystem. 2022-08-22 14:19:30 +02:00
da4694eb6b
debian/control: description to long :) 2022-08-22 14:19:30 +02:00
e2d3e3e59f
debian/rules pass $DEB_VERSION as VersionString to linker. 2022-08-22 14:19:29 +02:00
189b4f2207
scripts/info.sh: remove program version, defined in Makefile. 2022-08-22 14:19:29 +02:00
d2db6ea4b3
set-version.sh: Update to handle debian/changes and PROGRAM_VERSION in Makefile. 2022-08-22 14:19:29 +02:00
4b3ae5431c
Makefile: Set VersionString variable when linking. 2022-08-21 23:52:26 +02:00
b67b5d6b7e
src/main.go: use a global variable to display version number, this should be set by the linker during build. 2022-08-21 20:46:40 +02:00
53bc1cfbd8
debian/control: Add extended description 2022-08-21 20:26:09 +02:00
83edcac967
debian/rules: pass PREFIX=/usr to INSTALL_FLAGS as debian packages should not install anything in /usr/local 2022-08-21 20:17:13 +02:00
08e7041246
debian/rules: pass "--buildmode=pie" in GOBUILDFLAGS to install. 2022-08-21 20:09:12 +02:00
d33abd05f6
debian/control: Should have Standards-Version = 4.5.0 2022-08-21 20:08:25 +02:00
e44a5ab86e
Makefile: in build target, skip creating build/.buildinfo. its not needed. 2022-08-21 20:08:01 +02:00
fe1beaa616
Makefile: remove GOCCFLAGS and GOLDFLAGS in favor for GOBUILDFLAGS 2022-08-21 20:03:03 +02:00
c2e0bef26e
src/main.go: in eventLoop() combine SIGINT and SIGTERM handling, they have the same functionality. 2022-08-21 15:02:27 +02:00
bd412bb0eb
src/main.go: in eventLoop() create a child logger with a signal parameter and use that to log messages. 2022-08-21 15:02:26 +02:00
8b86a5d34b
src/main.go: Fix a comment. 2022-08-21 15:02:26 +02:00
44c1d690ef
src/main.go: indentation fix. 2022-08-21 14:31:31 +02:00
2832b50fe7
src/main.go: in event loop, also listen for SIGTERM and gracefully shutdown the program. 2022-08-21 14:28:22 +02:00
b2c6589408
src/main.go: Log return from spawnTcpServer() 2022-08-21 14:15:06 +02:00
14d833e174
src/main.go: Only start event loop if server started correctly. 2022-08-21 14:12:03 +02:00
0e7ed54c1a
src/server.go: make spawnTcpServer() return error and remove log calls. 2022-08-21 14:09:17 +02:00
4653790df4
src/main.go: do graceful shutdown on interrupt signal. 2022-08-21 14:01:17 +02:00
d4cb1a92f9
src/main.go: switch go routine/main thread order. run spawnTcpServer() in go routine and run event loop in main thread. 2022-08-21 13:46:45 +02:00
6907b3ce75
src/main.go: skip logging "TCP Server started" its done in spawnTcpServer() 2022-08-21 13:35:31 +02:00
def3b41842
src/server.go: in SpawnTcpServer, do server.Connect() and then server.Listen() 2022-08-21 13:34:56 +02:00
4dd19df65b
.gitignore: ignore *.swp files. 2022-08-21 13:33:58 +02:00
1577707b7d
go.mod: update eosswedenorg/tcp_server to v0.1.1 2022-08-21 13:27:21 +02:00
7043d67945
Build debian packages using specification files instead of shell script. 2022-08-19 17:07:26 +02:00
6f8a3db85e
scripts/install_linux.sh: install systemd service file in /lib/systemd/system and create a symlink to it in /etc/systemd/system 2022-08-19 15:36:57 +02:00
792632d0e5
scripts/templates/config: prefix OPTS variable so it wont collide so easy with other environment variables. 2022-08-19 13:53:28 +02:00
fd04b3364f
scripts/install_linux.sh install systemd/init.d config file in /etc/default/eosio-api-healthcheck instead of /etc/eosio-api-healthcheck/env
Its the standard way for init.d but alot of systemd services uses it also.
2022-08-19 13:48:38 +02:00
0001c28ca7
scripts/install_freebsd.sh: call log_install for each file. 2022-08-19 13:31:24 +02:00
1f2252b2b5
scripts/install_linux.sh: call log_install for each file. 2022-08-19 13:31:15 +02:00
787adca5bd
Adding scripts/functions/log_install.sh 2022-08-19 13:30:37 +02:00
4a7d74594e
set-version.sh: update version in pkg_info.sh instead of Makefile 2022-08-19 13:26:02 +02:00
f63723a6f8
Remove package.sh. packages can be created by make package_debian or package_freebsd 2022-08-19 13:26:02 +02:00
f4a39783b1
Split scripts/build*.sh into install and package scripts. 2022-08-19 13:26:01 +02:00
3fce1f558b
src/api/v2.go: rename file to eosio_v2.go 2022-08-18 23:19:10 +02:00
c8361f6a44
src/api/v1.go: rename file to eosio_v1.go 2022-08-18 23:18:54 +02:00
f98e2ed794
src/api/eosio_contract.go: use utils.Time 2022-08-18 12:08:05 +02:00
e5ddffbc5a
src/api/v1.go: use utils.Time 2022-08-18 12:08:05 +02:00
d3d0fb11d7
Adding src/utils/time.go 2022-08-18 12:08:05 +02:00
c8a128b657
src/api/eosio_contract.go: do not return a message to haproxy if postgres is down. 2022-08-17 17:46:32 +02:00
ec705687bc
src/api: rename eosio-contract.go to eosio_contract.go 2022-08-17 17:46:05 +02:00
ec44e35488
Adding src/api/eosio_contract_test.go 2022-08-17 17:45:00 +02:00
fa6c0bf8a1
src/api/eosio-contract.go: Add SetTime() and GetTime() 2022-08-17 17:28:01 +02:00
816a38acae
Adding src/api/log_params_test.go 2022-08-17 16:55:22 +02:00
a550f67dca
src/api/v2_test.go: Add test for LogInfo() 2022-08-17 16:55:05 +02:00
7f45b746c1
src/api/v1_test.go: Add test for LogInfo() 2022-08-17 16:54:56 +02:00
bfb74e8e48
README.md: Change "failed" to "fail" in response status code. 2022-08-17 16:38:18 +02:00
47ec8ae86e
Adding src/api/v2_test.go 2022-08-17 16:37:23 +02:00
b8bc300c70
go.sum: cleanup. 2022-08-17 11:40:44 +02:00
838f199b30
go.mod: require testify 2022-08-17 11:40:23 +02:00
43b3b36d09
Adding src/api/v1_test.go 2022-08-17 11:40:08 +02:00
f16dced21c
src/api/v1.go: Adding SetTime() and GetTime() 2022-08-17 11:39:28 +02:00
513beee79a
src/api/eosio-contract.go: remove comment. 2022-08-17 11:19:11 +02:00
ccd6cb46d2
Adding src/utils/json_test.go 2022-08-16 20:05:31 +02:00
589e2ad679
Adding .github/workflows/test.yml 2022-08-16 20:03:54 +02:00
14c4e3764c
Remove src/utils/is_url.go 2022-08-16 20:03:31 +02:00
890ea537c6
Makefile: add test target. 2022-08-16 20:03:13 +02:00
83a2ddf2ed
src/server.go: use code from parse_request.go 2022-08-16 20:02:31 +02:00
da8a53aa3c
Adding src/parse_request.go 2022-08-16 19:48:23 +02:00
5d27bf0ad2
src/api: change v1 and v2 constructor to not expose eosapi package structs. 2022-08-16 19:46:39 +02:00
303995ffda
src/server.go: remove support for old format. 2022-08-15 13:34:49 +02:00
b1f39ea9fe
Version 1.2.2 2022-08-15 13:14:48 +02:00
768fabe15d
src/server.go: Remove some more messages in haproxy responses. 2022-08-15 12:47:28 +02:00
7215e34152
src/server.go: whoops, even the backward support for old format is wrong.
https://xkcd.com/1739
2022-08-15 12:23:34 +02:00
1a3594af54
Version 1.2.1 2022-08-12 18:03:41 +02:00
24e5daa4ea
go.mod: update haproxy to v0.1.1 2022-08-12 18:02:57 +02:00
ec7a46f5ae
src/server.go: Add test api. 2022-08-12 17:57:24 +02:00
1d6a9c0950
Adding src/api/test.go 2022-08-12 17:56:59 +02:00
879d613b46
src/api: do not send a message in haproxy response (it does not like that). 2022-08-12 17:16:01 +02:00
ed91320a1d
Makefile: remove deps. 2022-08-12 16:33:51 +02:00
64f6e25b21
README.md: remove documentation regarding "make deps" as it's not needed when using go modules files. 2022-07-18 16:19:07 +02:00
34d7192f2a
README.md: Typo fix 2022-07-18 13:57:14 +02:00
99958e2165
src/server.go: rename arguments.block_time to num_blocks. and convert to seconds for v1/contract but not v2. 2022-05-31 10:22:27 +02:00
a3be529b78
Version 1.2 2022-05-18 10:09:49 +02:00
e0174ea3b7
src/server.go: Minor cleanup. 2022-05-17 18:54:08 +02:00
32619b293f
src/server.go: Add backward support for the old request format. 2022-05-17 18:52:17 +02:00
1912ef1790
Adding src/utils/is_url.go 2022-05-17 18:51:25 +02:00
affc56393e
src/server.go: fix an out-of-bounds bug in request parameter parsing code. 2022-05-17 18:50:58 +02:00
4ff008b312
Version 1.2-rc2 2022-03-02 16:59:45 +01:00
3aece958b1
Update to github.com/eosswedenorg-go/haproxy@v0.1.0 2022-03-02 16:58:32 +01:00
fa740af0b1
src/api/eosio-contract.go: copy paste error. should ofc not be Postgres in the Redis statement. 2022-03-02 16:29:21 +01:00
3303ff0905
go.mod: skip "internal" and use the root module and path. 2022-03-02 16:12:13 +01:00
bc3f859a8e
Makefile: add .PHONY target 2022-03-02 16:00:43 +01:00
46fd016d10
Makefile: move build/.buildinfo target to build/$(PROGRAM_NAME) 2022-03-02 16:00:43 +01:00
ec3a9bfac7
README.md: Document contract api. 2022-03-02 16:00:42 +01:00
b5c7b7c4d1
Remove logfile 2022-03-02 16:00:22 +01:00
c459999f88
Version 1.2-rc1 2022-03-02 16:00:22 +01:00
bb375296d8
src/server.go: adding "contract" api 2022-03-02 16:00:22 +01:00
415b1346dc
Adding src/api/eosio-contract.go 2022-03-02 16:00:21 +01:00
be945886e4
src/server.go: don't fallback to v1 api, return error on invalid api instead. 2022-03-02 16:00:21 +01:00
f6aabb7ed8
Change order of request parameters: api field moved from position 3 to 1 and are now required. 2022-03-02 16:00:21 +01:00
014027006f
src/api/v2.go: in LogInfo() skip "host" if it's zero length. 2022-03-02 16:00:21 +01:00
aa0b6998b8
src/api/v1.go: in LogInfo() skip "host" if it's zero length. 2022-03-02 16:00:20 +01:00
d5ec841586
src/api/interface.go: make LogInfo() return LogParams 2022-03-02 16:00:20 +01:00
1b53650723
Adding src/api/log_params.go 2022-03-02 16:00:20 +01:00
8e41cbfc5b
src/api/interface.go: remove Name() and define LogInfo() instead. 2022-03-02 16:00:19 +01:00
400ec204bc
README.md: rename parameter 3. version to api as it can be more generic then just different versions. 2022-03-02 16:00:19 +01:00
ddc7406a4c
src/server.go: refactor eosio v1/v2 api code into it's own module that implements a common interface 2022-03-02 16:00:19 +01:00
fa9a943215
Convert hard tabs to soft. 2022-03-02 15:56:29 +01:00
1dc31db4e1
src/main.go: set parameters for getopt.Usage() 2022-03-02 15:56:28 +01:00
15568153c9
src/main.go: Add --help|-h flag to getopt 2022-03-02 15:56:28 +01:00
44a01344c7
Replace local eosapi with github.com/eosswedenorg-go/eosapi 2022-03-02 15:54:45 +01:00
1d8b47762e
replace standard logger for github.com/inconshreveable/log15 2022-03-02 15:53:36 +01:00
107df930f1
src/main.go: log tcp server address 2022-03-02 15:50:36 +01:00
3a4c827f8e
replace github.com/firstrow/tcp_server with github.com/eosswedenorg-go/tcp_server 2022-03-02 15:50:05 +01:00
59bd699065
Replace local pid module with the one located at github.com/eosswedenorg-go/pid 2022-03-02 15:48:39 +01:00
10a12816fa
Replace local haproxy module with the one located at github.com/eosswedenorg-go/haproxy 2022-03-02 15:47:30 +01:00
88e415cb56
Adding LICENSE 2022-01-01 14:46:38 +01:00
f522146fbf Version 1.1 2021-12-30 19:08:39 +01:00
caf86bc797 compile.sh: add "-t" flag to usage string. 2021-12-30 19:07:37 +01:00
c552551348 compile.sh: remove "-p" flag from getopt. 2021-12-30 19:07:17 +01:00
26369545af .github/workflows/release.yml: Build FreeBSD packages for more architectures. 2021-12-30 19:01:39 +01:00
ed1341a72b scripts/build_freebsd.sh: add $GOARCH to tar filename. 2021-12-30 18:56:02 +01:00
4c5c74be31 scripts/build.sh: read and export variables from build/.buildinfo 2021-12-30 18:55:23 +01:00
f91e45e5ff package.sh: read target os from build/.buildinfo instead of binary. 2021-12-30 18:54:56 +01:00
55e149ddd6 Makefile: output data from "go env" to build/.buildinfo 2021-12-30 18:52:19 +01:00
a757c0dde5 Rename generated package info file from scrtips/info to scripts/pkg_info 2021-12-30 18:49:25 +01:00
8085eaa81d Add .github/workflows/release.yml 2021-12-30 18:05:15 +01:00
91bad080ee Modify package scripts to use build/ directory to store tmp directory and output files. 2021-12-30 17:35:18 +01:00
6ffc6f66c5 Merge branch 'freebsd-newsyslog-signal-on-rotate'
# Conflicts:
#	src/main.go
2021-12-24 11:09:17 +01:00
0ddbf6dea0 src/main.go: newsyslog actually sends SIGHUP, not SIGUSR1 2021-12-24 11:06:30 +01:00
8be4466d66 src/main.go: in setLogFile() check for null when closing old FD and also check error from Close() 2021-12-24 11:05:47 +01:00
2470062c3d scripts/templates/rc.conf: use "LOG_FILE" variable. 2021-12-24 11:04:19 +01:00
9532a8d5ef scripts/templates/rc.conf: pass logfile as "-l" flag 2021-12-24 11:03:18 +01:00
b8b11b1d66 Convert to go module 2021-12-23 16:47:15 +01:00
9781ee6a55 src/eosapi/functions.go: "github.com/liamylian/jsontime/v2" should be "github.com/liamylian/jsontime/v2/v2" 2021-12-23 16:46:55 +01:00
5907d96176 src/eosapi/functions.go: import jsontime with a more descriptive name than "v2" 2021-12-23 16:25:53 +01:00
82c32d7901 Version 1.0 2021-12-02 13:23:19 +01:00
4375afa4fe Adding set-version.sh 2021-12-02 13:23:03 +01:00
6cef421a34 README.md: Add more documentation for compiling and packaging 2021-12-02 12:56:57 +01:00
15a4566b3b src/main.go: add -v and --version flag. 2021-12-02 12:56:09 +01:00
de78a7c622 Makefile: get rid of package target (make get confused by package.sh file) 2021-12-02 12:55:29 +01:00
9cf1c84ae2 compile.sh: move package stuff to package.sh 2021-12-02 12:54:42 +01:00
f782177bec scripts/build.sh: Adding some information output. 2021-12-02 12:46:44 +01:00
90c06e7d9f Makefile: don't require build for package target. 2021-12-02 12:41:54 +01:00
324356f9f4 Merge branch 'master' into devel 2020-11-04 13:59:58 +01:00
d6cc9ac185 Version 0.3.5 2020-11-04 13:59:23 +01:00
69253eaab3 Minor indentation fixes. 2020-11-02 10:43:07 +01:00
xebb
2a521ab333 Adding check for HTTPStatusCode to support varnish 2020-10-11 11:51:06 +02:00
823832c94e src/main.go: act on the SIGUSR1 signal (sent by logrotate daemon) and reopen log file. 2020-06-26 18:10:05 +02:00
c4e404f873 src/main.go: rewrite openlog() to a more specific setLogFile() function. 2020-06-26 18:04:46 +02:00
184302b9e4 freebsd: tell newsyslog where the pid file is. 2020-06-26 14:02:07 +02:00
9e8ee93983 src/main.go: adding "--log,-l" command line flag to enable file logging. 2020-06-26 14:01:52 +02:00
fe8724aae5 move some "non server" code from src/server.go to src/main.go 2020-06-26 13:47:48 +02:00
dc28fbd762 scripts/templates/newsyslog.conf: rotate at 10:00 instead of 00:00 2020-06-26 03:41:30 +02:00
d7e643fd73 Version 0.3.4 2020-06-24 17:51:36 +02:00
1abb1c8249 Merge remote-tracking branch 'origin/bugfix/json-float64-parse-error' into devel 2020-06-24 17:51:21 +02:00
d1c1447758 README.md: Document go-lang version. 2020-06-24 17:51:04 +02:00
c214908c0c Rewrite the log module.
It is now cleaner and acts as a wrapper around the standard go log module.
2020-06-24 17:45:14 +02:00
5d5d7bb5be Makefile: make "scripts/info" rule a phony one. so that it's always generated. 2020-06-24 14:45:05 +02:00
ba6b79ae0e src/server.go: in check_api_v2() use utils.JsonGetInt64() to safely get a int64 value from json.
If json contains "nil" value, the type assertion will fail. JsonGetInt64() will in that case return "0"
2020-06-24 14:44:14 +02:00
32faaaf418 Adding src/utils/json.go 2020-06-24 14:44:14 +02:00
aaf0b35b93 compile.sh: hack freebsd package abit. 2020-06-23 17:01:08 +02:00
23f8a09320 Makefile: compile without debug info per default. 2020-06-23 16:53:35 +02:00
dd6d636a43 Version 0.3.3 2020-06-23 13:36:56 +02:00
1a7ee2e148 README.md: document the 'host' request paramter. 2020-06-23 13:35:28 +02:00
5481dd7d32 README.md: Correcting+Cleanup request parameters documentation. 2020-06-23 13:30:03 +02:00
a310cb041d src/server.go: make tcp message function a "real" function instead of a inline one. 2020-06-23 13:07:08 +02:00
ef13af4eb7 src/server.go: Minor cleanup. 2020-06-23 12:56:47 +02:00
66bc6f97af src/server.go: add "host" as a optional fourth parameter. 2020-06-23 12:56:47 +02:00
3aba653038 Define eosapi.ReqParams struct that includes a optional Host parameter.
If left empty, Host parsed from eosapi.ReqParams.Url will be used (like before).
2020-06-23 12:56:47 +02:00
bb8cb86fc0 Version 0.3.2 2020-06-11 19:28:14 +02:00
bf57dbb116 scripts/templates/rc.conf: stop command is not needed as rc can handle it by itself. 2020-06-11 19:28:02 +02:00
56cddd8e24 scripts/templates/rc.conf: pass "-p" flag (create pidfile) to program. 2020-06-11 19:04:09 +02:00
e0c7cfcc62 src/server.go: Use pid package and write pid file. 2020-06-11 19:01:32 +02:00
060535f595 Adding src/pid/pid.go 2020-06-11 19:01:32 +02:00
2b823c1dd3 Adding getopts package to parse pid file path. 2020-06-11 19:01:32 +02:00
83688c4b48 Make: minor fix. 2020-06-11 18:16:38 +02:00
4f1fd33ac7 scripts/build_freebsd.sh: make rc script executable 2020-06-11 18:12:13 +02:00
abde77f291 scripts/templates/rc.conf: append to logfile. 2020-06-11 17:12:38 +02:00
fab8c1a589 scripts/build.sh: move deb specific variables to deb file 2020-06-11 14:17:08 +02:00
c5a8f20c04 scripts: move template files to "templates" directory 2020-06-11 14:13:07 +02:00
00d96cf045 scripts/build_freebsd.sh: create newsyslog config instead of logrotate 2020-06-11 14:09:09 +02:00
cbc638bef0 scripts/build.sh: adding TEMPLATE_DIR variable 2020-06-11 14:08:44 +02:00
590ad836fc Adding: scripts/templates/newsyslog.conf 2020-06-11 14:08:23 +02:00
c6abbfda72 scripts/build_freebsd.sh: package logrotate file. 2020-06-11 13:36:59 +02:00
977e0cf3eb Make: fixing incorrect rule. 2020-06-11 13:36:37 +02:00
7cbecce1ba Adding freebsd package script. 2020-06-09 17:54:20 +02:00
4536c09d5c Make: create info file that contains the variable information. this file is then sourced by build.sh 2020-06-09 17:54:20 +02:00
767508c4f0 scripts/build_deb.sh: refactor common code to build.sh 2020-06-09 17:54:20 +02:00
e547ac7062 adding scripts/rc.template 2020-06-09 17:54:20 +02:00
41cb29703b Adding compile.sh 2020-04-29 14:40:00 +02:00
d30f4e16bc Version 0.3.1 2020-03-20 15:03:03 +01:00
a08b1f3458 src/eosapi/functions.go: in send() u.Host can contain port also. so we need to remove it when setting the Host header. 2020-03-20 14:58:59 +01:00
c222eb9945 Version 0.3.0 2020-03-20 14:36:13 +01:00
01aa9a0fff Adding logrotate config 2020-03-20 14:31:48 +01:00
407049096d Adding rsyslog config. 2020-03-20 13:59:26 +01:00
4ef714a750 Move source files to "src" folder. 2020-03-06 11:35:36 +01:00
8e8393d560 scripts/template.service: cleanup. 2020-03-06 11:29:29 +01:00
5dc55e9ac7 eosapi/functions.go: minor fixes. 2020-03-06 11:28:09 +01:00
a2327555f9 eosapi/types.go: adding some comments. 2020-03-06 11:26:04 +01:00
70ad80763f README.md: update parameter delimiter in requests. 2020-03-06 11:23:57 +01:00
9717354e22 combine host, port parameters into one string and add scheme. 2020-03-06 11:23:28 +01:00
07c73c2b4e scripts/build_deb.sh: append linux dist id and release to output filename. 2020-02-07 08:43:29 +01:00
64 changed files with 3335 additions and 442 deletions

139
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,139 @@
name: Package
on:
release:
types: [ created ]
jobs:
cross-compile:
strategy:
fail-fast: false
matrix:
os: [ linux, freebsd ]
arch: [ 386, amd64, arm, arm64 ]
name: Crosscompile - ${{matrix.os}}-${{matrix.arch}}
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.18
- name: compile
id: compile
run: |
./compile.sh --target ${{matrix.os}} -a ${{matrix.arch}}
FILE=$(find build -type f | head -1)
echo "::set-output name=version::$(sed -n 's/.*PROGRAM_VERSION\s*=\s*//p' Makefile)"
echo "::set-output name=filename::$FILE"
echo "::set-output name=name::$(basename $FILE)"
echo "::set-output name=mime::$(file -bi $FILE)"
- name: Upload
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_name: ${{ steps.compile.outputs.name }}-${{steps.compile.outputs.version}}-${{matrix.os}}-${{matrix.arch}}
asset_path: ${{ steps.compile.outputs.filename }}
asset_content_type: ${{ steps.compile.outputs.mime }}
package-ubuntu:
strategy:
fail-fast: false
matrix:
os: [ ubuntu-20.04 ]
name: Package - ${{matrix.os}}
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.18
- name: Install build dependencies
run: |
sudo apt-get -y update
sudo apt-get -y install build-essential fakeroot debhelper
- name: Package
id: package
run: |
make package_debian
DEB_FILE=$(ls ../*.deb | head -1)
echo "::set-output name=deb_filename::$DEB_FILE"
echo "::set-output name=deb_name::$(basename $DEB_FILE)"
CH_FILE=$(ls ../*.changes | head -1)
echo "::set-output name=ch_filename::$CH_FILE"
echo "::set-output name=ch_name::$(basename $CH_FILE)"
INFO_FILE=$(ls ../*.buildinfo | head -1)
echo "::set-output name=info_filename::$INFO_FILE"
echo "::set-output name=info_name::$(basename $INFO_FILE)"
- name: Upload (package)
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_name: ${{ steps.package.outputs.deb_name }}
asset_path: ${{ steps.package.outputs.deb_filename }}
asset_content_type: application/x-deb
- name: Upload (.changes)
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_name: ${{ steps.package.outputs.ch_name }}
asset_path: ${{ steps.package.outputs.ch_filename }}
asset_content_type: text/plain
- name: Upload (buildinfo)
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_name: ${{ steps.package.outputs.info_name }}
asset_path: ${{ steps.package.outputs.info_filename }}
asset_content_type: text/plain
package-freebsd:
strategy:
fail-fast: false
matrix:
arch: [ 386, amd64, arm, arm64 ]
name: Package - FreeBSD (${{matrix.arch}})
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.18
- name: Package
id: package
run: |
GOARCH=${{matrix.arch}} make package_freebsd
FILE=$(ls build/*.tar.gz | head -1)
echo "::set-output name=filename::$FILE"
echo "::set-output name=name::$(basename $FILE)"
- name: Upload
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_name: ${{ steps.package.outputs.name }}
asset_path: ${{ steps.package.outputs.filename }}
asset_content_type: application/gzip

40
.github/workflows/test.yml vendored Normal file
View file

@ -0,0 +1,40 @@
name: Test
on:
- push
- pull_request
jobs:
cross-compile:
strategy:
fail-fast: false
matrix:
os: [ linux, freebsd ]
arch: [ 386, amd64, arm, arm64 ]
name: Crosscompile - ${{matrix.os}}-${{matrix.arch}}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.18
- name: compile
id: compile
run: |
./compile.sh --target ${{matrix.os}} -a ${{matrix.arch}}
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.18
- name: Test
run: go test -v ./...

2
.gitignore vendored
View file

@ -1 +1,3 @@
*.swp
.vscode/
build/ build/

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020-2023 Sw/eden
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,30 +1,47 @@
PROGRAM_NAME = antelope-api-healthcheck
export PROGRAM_VERSION = 1.4.6
GO = go GO = go
GOCCFLAGS = -v
GOLDFLAGS =
PREFIX = /usr/local PREFIX = /usr/local
export GOOS = $(shell $(GO) env GOOS)
export GOARCH = $(shell $(GO) env GOARCH)
GOBUILDFLAGS = -v -ldflags='-v -s -w -X main.VersionString=$(PROGRAM_VERSION)'
PROGRAM_NAME=eosio-api-healthcheck DPKG_BUILDPACKAGE = dpkg-buildpackage
SOURCES=server.go DPKG_BUILDPACKAGE_FLAGS = -b -uc
DEPENDANCIES= github.com/firstrow/tcp_server \
github.com/liamylian/jsontime/v2 \
github.com/imroc/req
.PHONY: all build/$(PROGRAM_NAME) build/antelope-v1-mock-server clean package_debian
all: build all: build
build: build/$(PROGRAM_NAME) build: build/$(PROGRAM_NAME)
build/$(PROGRAM_NAME) : $(SOURCES) build/$(PROGRAM_NAME) : $(SOURCES)
$(GO) build -o $@ $(GOCCFLAGS) $(GOLDFLAGS) $< $(GO) build -o $@ $(GOBUILDFLAGS) cmd/antelope-api-healtcheck/main.go
deps: build/antelope-v1-mock-server:
$(GO) get $(DEPENDANCIES) $(GO) build -o $@ $(GOBUILDFLAGS) cmd/antelope-v1-mock-server/main.go
package_deb: build test-utils: build/antelope-v1-mock-server
export PACKAGE_NAME="$(PROGRAM_NAME)" \
export PACKAGE_VERSION="0.2.0" \ test:
export PACKAGE_PREFIX=$(PREFIX:/%=%) \ $(GO) test -v ./...
export PACKAGE_PROGRAM="build/$(PROGRAM_NAME)" \
&& ./scripts/build_deb.sh coverage:
$(GO) test -cover -v ./...
install: build
PREFIX=$(PREFIX) DESTDIR=$(DESTDIR) scripts/install.sh $(GOOS)
package:
PKGROOT=$(DESTDIR) BUILDDIR=$(realpath build) scripts/package.sh $(PKGTYPE)
package_debian:
$(DPKG_BUILDPACKAGE) $(DPKG_BUILDPACKAGE_FLAGS)
package_freebsd: PKGTYPE = freebsd
package_freebsd: GOOS = freebsd
package_freebsd: DESTDIR = build/freebsdroot
package_freebsd: install package
clean: clean:
$(GO) clean $(GO) clean

View file

@ -1,6 +1,25 @@
# EOSIO API Healthcheck for HAProxy # Antelope API Healthcheck for HAProxy
This program implements EOSIO healthcheck for HAProxy over TCP. [![Test](https://github.com/eosswedenorg/antelope-api-healthcheck/actions/workflows/test.yml/badge.svg)](https://github.com/eosswedenorg/antelope-api-healthcheck/actions/workflows/test.yml)
[![Report](https://goreportcard.com/badge/github.com/eosswedenorg/antelope-api-healthcheck)](https://goreportcard.com/report/github.com/eosswedenorg/antelope-api-healthcheck)
This program implements Antelope healthcheck for HAProxy over TCP.
## Compiling
You will need golang version `1.16` or later to compile the source.
compile with `compile.sh` script
```sh
./compile.sh
```
Execute `./compile.sh --help` to see all available flags to crosscompile for different systems/architectures.
### Package
run `./package.sh` to generate package. Debian (.deb) and FreeBSD are supported.
## TCP Protocol ## TCP Protocol
@ -8,21 +27,20 @@ The protocol is simple and has 4 rules.
1. Data is transmitted in `packets` encoded in ascii and ends with newline `\n`. 1. Data is transmitted in `packets` encoded in ascii and ends with newline `\n`.
2. There are two types of packages: `Request` and `Response`. Each `Request` has exactly one `Response`. 2. There are two types of packages: `Request` and `Response`. Each `Request` has exactly one `Response`.
3. Each parameter inside a `Request` is separated by `:` 3. Each parameter inside a `Request` is separated by `|`
4. Each response contains exactly one `status code` (see below) 4. Each response contains exactly one `status code` (see below)
### Request ### Request
The following parameters are supported in a request and are ordered from The following parameters are supported in a request and are ordered from
first to last below: first to last below:
| # | Name | Required | Description | | # | Name | Required | Description |
| - | ---------- | -------- | ----------------------------------------------------------------------------- | | - | ---------- | ------------------------- | -------------------------------------------------------------------------------------------- |
| 1 | Host | Yes | IP/Hostname to the api. | | 1 | api | Yes | Type of API to check against,`v1` = standard, `v2` = Hyperion, `atomic` = atomicassets |
| 2 | Port | No | Port number to the api (default `80`) | | 2 | url | Yes (port default `80`) | http url to the api.`http(s)://<ip-or-domain>(:<port>)` |
| 3 | num_blocks | No | Number of blocks the api can drift before reported `down` (default 10) | | 3 | num_blocks | No (default `10`) | Number of blocks the api can drift before reported `down` |
| 4 | version | No | API Version to check against, `v1` = standard, `v2` = Hyperion (default `v1`) | | 4 | host | No (default from `url`) | Value to send in the `HTTP Host Header` to the API |
### Response ### Response
@ -30,10 +48,10 @@ The api can respond with exactly one `status code`.
See [HAproxy documentation](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.2-agent-check) for more information See [HAproxy documentation](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.2-agent-check) for more information
| code | Description | | code | Description |
| --------- | ---------------------------------------------------------- | | ----------- | ------------------------------------------------------------ |
| `up` | Api is healthy | | `up` | Api is healthy |
| `down` | Api is not healthy | | `down` | Api is not healthy |
| `failed` | The program failed to read the status from the api. | | `fail` | The program failed to read the status from the api. |
| `maint` | Api is set in maintenance mode (not used) | | `maint` | Api is set in maintenance mode (not used) |
| `ready` | Api is ready again after being in `maint` state (not used) | | `ready` | Api is ready again after being in `maint` state (not used) |
| `stopped` | Api has been stopped manually (not used) | | `stopped` | Api has been stopped manually (not used) |

View file

@ -0,0 +1,208 @@
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
"github.com/eosswedenorg-go/pid"
"github.com/eosswedenorg/antelope-api-healthcheck/internal/server"
"github.com/eosswedenorg/antelope-api-healthcheck/internal/utils"
log "github.com/inconshreveable/log15"
"github.com/pborman/getopt/v2"
)
// Command line flags
// ---------------------------------------------------------
var (
logFile string
pidFile string
)
// Global variables
// ---------------------------------------------------------
// Version string, should be updated by the go linker (by passing "-X main.VersionString=value" to the linker)
// see: https://pkg.go.dev/cmd/link
var VersionString string = "-"
// File descriptor to the current log file.
var logfd *os.File
var (
logfmt log.Format
logger log.Logger
// TCP Server
srv *server.Server
)
// argv_listen_addr
// Parse listen address from command line.
//
// ---------------------------------------------------------
func argv_listen_addr() string {
var addr string
argv := getopt.Args()
if len(argv) > 0 {
addr = argv[0]
} else {
addr = "127.0.0.1"
}
addr += ":"
if len(argv) > 1 {
addr += argv[1]
} else {
addr += "1337"
}
return addr
}
func setLogFile() {
// Open file
fd, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
if err != nil {
logger.Error(err.Error())
}
// Try close if old descriptor is defined.
if logfd != nil {
if err = logfd.Close(); err != nil {
logger.Error(err.Error())
}
}
// Update variable and set log writer.
logfd = fd
logger.SetHandler(log.StreamHandler(logfd, logfmt))
}
// signalEventLoop()
// Initialize event channel for OS signals
// and runs an event loop.
//
// ---------------------------------------------------------
func signalEventLoop() {
// Setup a channel
sig_ch := make(chan os.Signal, 1)
// subscribe to SIGHUP signal.
signal.Notify(sig_ch, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
// Event loop
var run bool = true
for run {
// Block until we get a signal.
sig := <-sig_ch
l := logger.New("signal", sig)
switch sig {
case syscall.SIGINT, syscall.SIGTERM:
l.Info("Program was asked to terminate.")
run = false
// Tell the server to close.
err := srv.Close()
if err != nil {
l.Error("Failed to close server", "error", err)
}
// SIGHUP is sent when logfile is rotated.
case syscall.SIGHUP:
msg := "Logfile was rotated: "
if logfd != nil {
setLogFile()
msg += "Filedescriptor was updated"
} else {
msg += "No Filedescriptor to update (most likely uses standard out/err streams)"
}
l.Info(msg)
default:
l.Warn("Unknown signal")
}
}
}
// main
//
// ---------------------------------------------------------
func main() {
var version bool
var usage bool
var logFormatter *string
// Set default timeout to 2 sec
// as haproxy "inter" parameter to healthcheck is set to 2s per default.
req_timeout := time.Second * 2
logger = log.Root()
// Command line parsing
getopt.SetParameters("[ip] [port]")
getopt.FlagLong(&usage, "help", 'h', "Print this help text")
getopt.FlagLong(&version, "version", 'v', "Print version")
getopt.FlagLong(&logFile, "log", 'l', "Path to log file", "file")
getopt.FlagLong(&pidFile, "pid", 'p', "Path to pid file", "file")
getopt.FlagLong(&req_timeout, "timeout", 't', "Set the maximum time before a request times out, valid prefixes are 's','ms','us'", "duration")
logFormatter = getopt.EnumLong("log-format", 0, []string{"term", "logfmt", "json", "json-pretty"}, "", "Log format to use: term,logfmt,json,json-pretty")
getopt.Parse()
if usage {
getopt.Usage()
return
}
if version {
fmt.Printf("Version: %s\n", VersionString)
return
}
logfmt = utils.ParseLogFormatter(*logFormatter)
// Open logfile.
if len(logFile) > 0 {
setLogFile()
} else {
logger.SetHandler(log.StreamHandler(os.Stdout, logfmt))
}
logger.Info("Process is starting", "pid", pid.Get())
if len(pidFile) > 0 {
logger.Info("Writing pidfile", "file", pidFile)
err := pid.Save(pidFile)
if err != nil {
logger.Error("Failed to write pidfile", "msg", err)
}
}
if req_timeout.Seconds() < 2 {
// Dont alow anything below 2 seconds. that is abit aggressive.
logger.Warn("Request timeout is less than the minimum. Setting it to 2 seconds", "req_timeout", req_timeout)
req_timeout = time.Second * 2
} else if req_timeout.Minutes() > 1.0 {
// Anything more than 1 min is too long :)
logger.Warn("Request timeout is more than the maximum. Setting it to 1 minute", "req_timeout", req_timeout)
req_timeout = time.Minute
}
// Create server
srv = server.New(argv_listen_addr(), server.WithTick(time.Second*10), server.WithTimeout(req_timeout))
// Run signal event loop in its own goroutine
go signalEventLoop()
// Run server
if err := srv.Run(); err != nil {
logger.Error("Server error", "error", err)
os.Exit(1)
}
}

View file

@ -0,0 +1,78 @@
package main
import (
"flag"
"fmt"
"math/rand"
"net/http"
"os"
"time"
"github.com/eosswedenorg-go/leapapi"
)
var (
listen_host = flag.String("h,host", "localhost", "Host to listen on.")
listen_port = flag.Int("p", 3333, "Port to listen to.")
delay = flag.Int("d", 0, "Delays responses randomly between 0 and int seconds.")
)
func getInfo(w http.ResponseWriter, r *http.Request) {
current_time := time.Now()
info := leapapi.Info{
ServerVersion: "c83ea9c2",
ServerVersionString: "0.0.0-debug",
ServerFullVersionString: "0.0.0-debug-c83ea9c21f60670a00627319ebbd233e6bb4f84904dbcfc894242ba38b2761d4",
HeadBlockNum: 1000,
HeadBlockID: "168d2cf232ca78e94d57a86301e35f110b6016358e05d49ab822df0a8aa988ea",
HeadBlockTime: current_time.UTC(),
ChainID: "1045fa26e1c5be590ae6114e73331152671f13c87eee60a2171387dcbc44da88",
HeadBlockProducer: "debugproducer",
LastIrreversableBlockNum: 900,
LastIrreversableBlockID: "5149254b9b6fd61a02403ebe3b45ade57642ed473295f33e2184e56966370a1f",
LastIrreversableBlockTime: current_time.Add(time.Second * -5).UTC(),
VirtualBlockCPULimit: 4000,
VirtualBlockNETLimit: 5000,
BlockCPULimit: 8000,
BlockNETLimit: 2000,
TotalCPUWeight: 60488453825414473,
TotalNETWeight: 101764028077814346,
ForkDBHeadBlockID: "7544799d7c2f511368cb94adc65223e1e2cc4cf9639ba07eef2421486a8dbfe5",
ForkDBHeadBlockNum: 100,
}
if *delay > 0 {
sleep_for := rand.Intn(*delay)
time.Sleep(time.Second * time.Duration(sleep_for))
}
payload, err := leapapi.Json().Marshal(&info)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
w.Header().Add("Content-Type", "application/json")
_, err = w.Write(payload)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
func main() {
rand.Seed(time.Now().Unix())
flag.Parse()
http.HandleFunc("/v1/chain/get_info", getInfo)
addr := fmt.Sprintf("%s:%d", *listen_host, *listen_port)
fmt.Println("Listening on:", addr)
err := http.ListenAndServe(addr, nil)
if err != nil {
panic(err)
}
}

72
compile.sh Executable file
View file

@ -0,0 +1,72 @@
#!/bin/bash
SYSTEMS=( windows linux freebsd )
ARCHS=( 386 amd64 amd64p32 arm arm64 ppc ppc64 )
function usage() {
echo "Usage: ${0##*/} [ -h|--help ] [ -t|--target <system> ] [ -a|--arch <arch> ]"
echo ""
echo " Valid systems:"
for i in "${SYSTEMS[@]}"; do
echo " * ${i}"
done
echo ""
echo " Valid architectures:"
for i in "${ARCHS[@]}"; do
echo " * ${i}"
done
echo ""
exit 1
}
options=$(getopt -n "${0##*/}" -o "ht:a:" -l "help,target:,arch:" -- "$@")
[ $? -eq 0 ] || usage
eval set -- "$options"
MAKE_TARGET="all"
while true; do
case $1 in
-t|--target)
shift
REGEX=$(echo "${SYSTEMS[@]}" | sed 's/[[:space:]]/|/g')
[[ ! "$1" =~ ^($REGEX)$ ]] && {
echo "Incorrect system '$1' provided"
usage
}
export GOOS=$1
;;
-a|--arch)
shift
REGEX=$(echo "${ARCHS[@]}" | sed 's/[[:space:]]/|/g')
[[ ! "$1" =~ ^($REGEX)$ ]] && {
echo "Incorrect architecture '$1' provided"
usage
}
export GOARCH=$1
;;
-h|--help) usage ;;
--) shift
break
;;
esac
shift
done
MESSAGE=""
if [ ! -z "${GOOS}" ]; then
MESSAGE="[\e[34m::\e[0m] Crosscompiling for: ${GOOS}"
fi
if [ ! -z "${GOARCH}" ]; then
MESSAGE="${MESSAGE} (${GOARCH})"
fi
[ ! -z "${MESSAGE}" ] && echo -e "" $MESSAGE
make -B ${MAKE_TARGET}

7
debian/.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
.debhelper/*
*.debhelper
*.log
*-stamp
*.substvars
files
pkgroot/*

192
debian/changelog vendored Normal file
View file

@ -0,0 +1,192 @@
antelope-api-healthcheck (1.4.6) unstable; urgency=medium
* Go Packages
- Update github.com/panjf2000/gnet/v2 from 2.2.9 to 2.3.1
- Update github.com/stretchr/testify from 1.8.3 to 1.8.4
-- Henrik Hautakoski <henrik@eossweden.org> Tue, 25 Jul 2023 17:28:29 +0200
antelope-api-healthcheck (1.4.5) unstable; urgency=medium
Maintenance release, dependancies updates.
* Go Packages
- Update github.com/panjf2000/gnet/v2 from 2.2.6 to 2.2.9
- Update github.com/stretchr/testify from 1.8.2 to 1.8.3
-- Henrik Hautakoski <henrik@eossweden.org> Tue, 23 May 2023 17:19:42 +0200
antelope-api-healthcheck (1.4.4) unstable; urgency=medium
[ Security ]
* CVE-2022-41723 - Uncontrolled Resource Consumption
Fixed by updating golang.org/x/net to patched version 0.7.0
[ Misc ]
* Go Packages
- Update golang.org/x/net from 0.4.0 to 0.7.0
- Update github.com/eosswedenorg-go/atomicasset from v0.1.1-0.20230206134606-4577244fa67a to v0.1.1
-- Henrik Hautakoski <henrik@eossweden.org> Tue, 04 Apr 2023 07:04:24 +0200
antelope-api-healthcheck (1.4.3) unstable; urgency=medium
[ Misc ]
* Typo fix.
* Go Packages
- github.com/stretchr/testify from 1.8.1 to 1.8.2
- github.com/inconshreveable/log15 from 0.0.0-20221122034931-555555054819 to 3.0.0-testing.5+incompatible
- github.com/panjf2000/gnet/v2 from 2.2.4 to 2.2.6
-- Henrik Hautakoski <henrik@eossweden.org> Tue, 04 Apr 2023 06:07:05 +0200
antelope-api-healthcheck (1.4.2) unstable; urgency=medium
[ Improvements ]
* API Check
- Default value for api timeout changed from 30s to 2s.
This makes sense because haproxy "inter" parameter is set to 2s per default.
* Linux install script
- Now installs `syslog-ng` configuration file.
* Misc
- Program now exits with correct status code "1" when an error occures.
-- Henrik Hautakoski <henrik@eossweden.org> Tue, 14 Feb 2023 09:11:43 +0100
antelope-api-healthcheck (1.4.1) unstable; urgency=medium
[ Bugfixes ]
* Fixing a bug where TCP connections were not closed after response was written.
[ Improvements ]
* API Check
- timeouts can now be configurable.
- "duration" and "duration_us" fields added to log row, these
values represents the api check duration.
* CLI
- new parameter `-t`, `--timeout` that specify the maximum duration of api checks.
[ Misc ]
* Go Packages
- Update github.com/panjf2000/gnet/v2 to v2.2.4
- Update github.com/eosswedenorg-go/leapapi to v0.2.3
- Update github.com/eosswedenorg-go/atomicassets to v0.1.1-0.20230206134606-4577244fa67a
-- Henrik Hautakoski <henrik@eossweden.org> Tue, 07 Feb 2023 09:29:40 +0100
antelope-api-healthcheck (1.4.0) unstable; urgency=medium
* Using github.com/panjf2000/gnet as tcp server library instead of github.com/eosswedenorg-go/tcp_server
[ Misc ]
* Go Packages
- Update github.com/eosswedenorg-go/haproxy to v1.0.1
- Update github.com/eosswedenorg-go/atomicasset to v0.1.0
-- Henrik Hautakoski <henrik@eossweden.org> Wed, 04 Jan 2023 14:03:41 +0100
antelope-api-healthcheck (1.3.1) unstable; urgency=medium
* Upgraded to github.com/eosswedenorg-go/leapapi@v0.2.1
That contains a bugfix for HTTP Host Header being sent without port.
This caused some antelope api's with `http-validate-host` enabled
to respond with `400 Bad Request` as the header and url did not match.
-- Henrik Hautakoski <henrik@eossweden.org> Mon, 12 Dec 2022 16:19:26 +0100
antelope-api-healthcheck (1.3.0) unstable; urgency=medium
Project and binary renamed from eosio-api-healthcheck to antelope-api-healthcheck
[ BREAKING Change: Config files ]
* Debian /etc/sysconfig/eosio-api-healthcheck
- File renamed to /etc/sysconfig/antelope-api-healthcheck
- EOSIO_API_HEALTCHECK_OPTS changed to ANTELOPE_API_HEALTCHECK_OPTS
* FreeBSD /etc/rc.conf
- eosio_api_healthcheck_args changed to antelope_api_healthcheck_args
- eosio_api_healthcheck_logfile changed to antelope_api_healthcheck_logfile
[ BREAKING Change: API ]
* Requests using "contract" as api is invalid from
this release and should use "atomic" instead.
For example: "contract|https://api.domain.com" should be changed to "atomic|https://api.domain.com"
[ Misc ]
* Go Packages
- Upgrade github.com/eosswedenorg-go/eosapi to github.com/eosswedenorg-go/leapapi v0.2.0
-- Henrik Hautakoski <henrik@eossweden.org> Fri, 25 Nov 2022 12:40:02 +0100
eosio-api-healthcheck (1.2.6) unstable; urgency=medium
* Go Packages
- Upgrade github.com/stretchr/testify to v1.8.1
- Upgrade github.com/eosswedenorg-go/eosapi to v0.1.3
- Upgrade github.com/inconshreveable/log15 to v0.0.0-20221122034931-555555054819
- Upgrade github.com/eosswedenorg-go/tcp_server to v0.2.1
* Eosio v1/v2 API's
- HTTP Errors are now handled by `eosapi`
This changes the log message abit and will report "Fail" instead of "Down" to haproxy.
-- Henrik Hautakoski <henrik@eossweden.org> Thu, 24 Nov 2022 14:57:00 +0100
eosio-api-healthcheck (1.2.5) unstable; urgency=medium
* Logging
- Add runtime support via "--log-format" cli flag to change the logging format.
Supported formats are: term, logfmt, json, json-pretty
-- Henrik Hautakoski <henrik@eossweden.org> Fri, 21 Oct 2022 13:42:23 +0200
eosio-api-healthcheck (1.2.4) unstable; urgency=medium
* Go Version
- Project now requires golang v1.16 or later to build.
* Go Packages
- Upgrade github.com/eosswedenorg-go/pid to v1.0.1
- Upgrade github.com/mattn/go-colorable to v0.1.13
- Upgrade github.com/eosswedenorg-go/eosapi to v0.1.1
- Upgrade github.com/eosswedenorg-go/eos-contract-api-client to v0.0.0-20220221105418-dc591fcc0dc5
- Upgrade github.com/eosswedenorg-go/tcp_server to v0.2.0
* Testing
- Improve unit tests to catch more bugs.
-- Henrik Hautakoski <henrik@eossweden.org> Thu, 13 Oct 2022 14:34:04 +0200
eosio-api-healthcheck (1.2.3) bionic; urgency=medium
* Signal handling
- Act on SIGINT (user input CTRL+C for example)
and gracefully shutdown the program.
- Act on SIGTERM (sent by systemd for example)
and gracefully shutdown the program
* Build system
- Separate install and packaging from build script into it's own scripts.
- Remove the debian package script and use "The debian standard"
(and debhelper) to build packages.
Files stored under the debian directory defines how the program is
built and package The `dpkg-buildpackage` script (and other tools)
uses these files to create a package.
* Testing: Adding test cases and make github automatically runs test on push.
* Go packages
- Upgrade to v0.1.1 for github.com/eosswedenorg-go/tcp_server
-- Henrik Hautakoski <henrik@eossweden.org> Mon, 22 Aug 2022 13:31:39 +0200

1
debian/compat vendored Normal file
View file

@ -0,0 +1 @@
10

19
debian/control vendored Normal file
View file

@ -0,0 +1,19 @@
Source: antelope-api-healthcheck
Section: introspection
Build-Depends:
debhelper (>= 11)
Standards-Version: 4.5.0
Vcs-Git: https://github.com/eosswedenorg/antelope-api-healthcheck.git
Vcs-Browser: https://github.com/eosswedenorg/antelope-api-healthcheck
Priority: optional
Maintainer: Henrik Hautakoski <henrik@eossweden.org>
Package: antelope-api-healthcheck
Section: introspection
Priority: optional
Architecture: amd64
Depends: ${shlibs:Depends}, ${misc:Depends}
Homepage: https://github.com/eosswedenorg/antelope-api-healthcheck
Description: HAproxy healthcheck program for Leap API.
This package provides all the files needed to
run the antelope-api-healthcheck TCP Server

27
debian/copyright vendored Normal file
View file

@ -0,0 +1,27 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: antelope-api-healthcheck
Upstream-Contact: Henrik Hautakoski <henrik@eossweden.org>
Source: https://github.com/eosswedenorg/antelope-api-healthcheck.git
Files: *
Copyright: 2020-2023 Sw/eden
License: MIT
License: MIT
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
.
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

15
debian/rules vendored Executable file
View file

@ -0,0 +1,15 @@
#!/usr/bin/make -f
include /usr/share/dpkg/default.mk
INSTALL_FLAGS := PREFIX=/usr GOOS=linux GOBUILDFLAGS="-v --buildmode=pie -ldflags=\"-v -s -w -X main.VersionString=$(DEB_VERSION)\""
%:
dh $@ -P debian/pkgroot
override_dh_auto_build:
override_dh_auto_install:
dh_auto_install --buildsystem=makefile -- $(INSTALL_FLAGS)
override_dh_usrlocal:
override_dh_gconf:

1
debian/source/format vendored Normal file
View file

@ -0,0 +1 @@
3.0 (native)

View file

@ -1,63 +0,0 @@
package eosapi;
import (
"fmt"
"time"
"io/ioutil"
"github.com/imroc/req"
"github.com/liamylian/jsontime/v2"
)
var json = v2.ConfigWithCustomTimeFormat;
func init() {
// EOS Api does not specify timezone in timestamps (they are always UTC tho).
v2.SetDefaultTimeFormat("2006-01-02T15:04:05", time.UTC);
}
func send(method string, host string, port int, uri string) (*req.Resp, error) {
// Go's net.http (that `req` uses) sends the port in the host header.
// nodeos api does not like that, so we need to provide our
// own Host header with just the host.
headers := req.Header{
"Host": host,
}
r := req.New()
return r.Do(method, fmt.Sprintf("http://%s:%d%s", host, port, uri), headers);
}
// GetInfo - Fetches get_info from API
// ---------------------------------------------------------
func GetInfo(host string, port int) (Info, error) {
var info Info;
r, err := send("GET", host, port, "/v1/chain/get_info");
if err == nil {
resp := r.Response()
body, _ := ioutil.ReadAll(resp.Body);
// Parse json
err = json.Unmarshal(body, &info);
}
return info, err;
}
func GetHealth(host string, port int) (Health, error) {
var health Health;
r, err := send("GET", host, port, "/v2/health");
if err == nil {
resp := r.Response()
body, _ := ioutil.ReadAll(resp.Body);
// Parse json
err = json.Unmarshal(body, &health);
}
return health, err;
}

View file

@ -1,23 +0,0 @@
package eosapi;
import "time"
// get_info format (not all fields).
type Info struct {
ServerVersion string `json:"server_version"`
HeadBlockNum int64 `json:"head_block_num"`
HeadBlockTime time.Time `json:"head_block_time"`
}
type Service struct {
Name string `json:"service"`
Status string `json:"status"`
Data map[string]interface{} `json:"service_data"`
Time int64 `json:"time"` // unix timestamp.
}
type Health struct {
VersionHash string `json:"version_hash"`
Health []Service `json:"health"`
}

59
go.mod Normal file
View file

@ -0,0 +1,59 @@
module github.com/eosswedenorg/antelope-api-healthcheck
go 1.18
require (
github.com/eosswedenorg-go/atomicasset v0.1.2
github.com/eosswedenorg-go/haproxy v1.0.1
github.com/eosswedenorg-go/leapapi v0.2.3
github.com/eosswedenorg-go/pid v1.0.1
github.com/inconshreveable/log15 v3.0.0-testing.5+incompatible
github.com/panjf2000/gnet/v2 v2.3.1
github.com/pborman/getopt/v2 v2.1.0
github.com/stretchr/testify v1.8.4
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/eosswedenorg-go/unixtime v0.1.1 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/pprof v0.0.0-20221219190121-3cb0bae90811 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/imroc/req/v3 v3.33.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/liamylian/jsontime/v2 v2.0.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/onsi/ginkgo/v2 v2.6.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-18 v0.2.0 // indirect
github.com/quic-go/qtls-go1-19 v0.2.0 // indirect
github.com/quic-go/qtls-go1-20 v0.1.0 // indirect
github.com/quic-go/quic-go v0.32.0 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/sonh/qs v0.6.2 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.21.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/exp v0.0.0-20221217163422-3c43f8badb15 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/sync v0.2.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/term v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.6.0 // indirect
gopkg.in/guregu/null.v4 v4.0.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

170
go.sum Normal file
View file

@ -0,0 +1,170 @@
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/eosswedenorg-go/atomicasset v0.1.2 h1:bvz5tVVyP8EHSQo9CPFZjdl1lICBisfoRwJv/SURMCs=
github.com/eosswedenorg-go/atomicasset v0.1.2/go.mod h1:iRs02PLQmJAFBlukjrReSwti+Ga2Rp2wtnBGQElMVg4=
github.com/eosswedenorg-go/haproxy v1.0.1 h1:N9tyQSvEDG9Fq+gBP0b7A8R5iZAqYCms2K6Nvqq8TfE=
github.com/eosswedenorg-go/haproxy v1.0.1/go.mod h1:rBXDRd72ifA/IvsZUpW8Q4gR5rbV/4DAuKC/lqDrwWQ=
github.com/eosswedenorg-go/leapapi v0.2.3 h1:2qGlP8wzZJCvjM9ol9t2uroCPMpV+wxF7lNl2NdG87M=
github.com/eosswedenorg-go/leapapi v0.2.3/go.mod h1:hyfjHswFjcnWMqOb+cYvTrT6l34S80GrFvfOdcYugnM=
github.com/eosswedenorg-go/pid v1.0.1 h1:W4AEnnNwb041SpNR1uTZ/KbJ0OTA5eqiqIR1Q5Ah6A0=
github.com/eosswedenorg-go/pid v1.0.1/go.mod h1:wiOB/JXGt4YA3+T0j0xmCGSc3Jxzb7Ti/Ftli1fgWu4=
github.com/eosswedenorg-go/unixtime v0.1.1 h1:fTNxDtQOKncv/zAc3TzwLQLA/YBVM5nlbsFWVEyMkds=
github.com/eosswedenorg-go/unixtime v0.1.1/go.mod h1:knU247oYvgCQD9MLYBdpi7qD1pTRgkSAWr9jbUx3S6c=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20221219190121-3cb0bae90811 h1:wORs2YN3R3ona/CXYuTvLM31QlgoNKHvlCNuArCDDCU=
github.com/google/pprof v0.0.0-20221219190121-3cb0bae90811/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/imroc/req/v3 v3.7.6/go.mod h1:3JIicOKEDHfCSYYNLb/ObZNpx64EV5y40VlHMwhUCzU=
github.com/imroc/req/v3 v3.33.2 h1:mqphLIo++p+IPYdjgP/Wd5rqXUjKvuEIst2U+EsLIwQ=
github.com/imroc/req/v3 v3.33.2/go.mod h1:cZ+7C3L/AYOr4tLGG16hZF90F1WzAdAdzt1xFSlizXY=
github.com/inconshreveable/log15 v3.0.0-testing.5+incompatible h1:VryeOTiaZfAzwx8xBcID1KlJCeoWSIpsNbSk+/D2LNk=
github.com/inconshreveable/log15 v3.0.0-testing.5+incompatible/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/liamylian/jsontime/v2 v2.0.0 h1:3if2kDW/boymUdO+4Qj/m4uaXMBSF6np9KEgg90cwH0=
github.com/liamylian/jsontime/v2 v2.0.0/go.mod h1:UHp1oAPqCBfspokvGmaGe0IAl2IgOpgOgDaKPcvcGGY=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
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/onsi/ginkgo/v2 v2.6.1 h1:1xQPCjcqYw/J5LchOcp4/2q/jzJFjiAOc25chhnDw+Q=
github.com/onsi/ginkgo/v2 v2.6.1/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo=
github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E=
github.com/panjf2000/ants/v2 v2.8.1 h1:C+n/f++aiW8kHCExKlpX6X+okmxKXP7DWLutxuAPuwQ=
github.com/panjf2000/gnet/v2 v2.3.1 h1:J7vHkNxwsevVIw3u/6LCXgcnpGBk5iKqhQ2RMblGodc=
github.com/panjf2000/gnet/v2 v2.3.1/go.mod h1:Ik5lTy2nmBg9Uvjfcf2KRYs+EXVNOLyxPHpFOFlqu+M=
github.com/pborman/getopt/v2 v2.1.0 h1:eNfR+r+dWLdWmV8g5OlpyrTYHkhVNxHBdN2cCrJmOEA=
github.com/pborman/getopt/v2 v2.1.0/go.mod h1:4NtW75ny4eBw9fO1bhtNdYTlZKYX5/tBLtsOpwKIKd0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
github.com/quic-go/qtls-go1-18 v0.2.0 h1:5ViXqBZ90wpUcZS0ge79rf029yx0dYB0McyPJwqqj7U=
github.com/quic-go/qtls-go1-18 v0.2.0/go.mod h1:moGulGHK7o6O8lSPSZNoOwcLvJKJ85vVNc7oJFD65bc=
github.com/quic-go/qtls-go1-19 v0.2.0 h1:Cvn2WdhyViFUHoOqK52i51k4nDX8EwIh5VJiVM4nttk=
github.com/quic-go/qtls-go1-19 v0.2.0/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI=
github.com/quic-go/qtls-go1-20 v0.1.0 h1:d1PK3ErFy9t7zxKsG3NXBJXZjp/kMLoIb3y/kV54oAI=
github.com/quic-go/qtls-go1-20 v0.1.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
github.com/quic-go/quic-go v0.32.0 h1:lY02md31s1JgPiiyfqJijpu/UX/Iun304FI3yUqX7tA=
github.com/quic-go/quic-go v0.32.0/go.mod h1:/fCsKANhQIeD5l76c2JFU+07gVE3KaA0FP+0zMWwfwo=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/sonh/qs v0.6.2 h1:ao0XNj2hXNdLW9Xk0L8zzEj1s3DjI7bDdG5QU8WUyxY=
github.com/sonh/qs v0.6.2/go.mod h1:ywKyX7vSo9R5dfgEQSCZ75tFzNkVUJZyK3/W6qGeHMQ=
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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8=
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
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.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/exp v0.0.0-20221217163422-3c43f8badb15 h1:5oN1Pz/eDhCpbMbLstvIPa0b/BEQo6g6nwV3pLjfM6w=
golang.org/x/exp v0.0.0-20221217163422-3c43f8badb15/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20220111093109-d55c255bac03/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
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.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
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-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg=
gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -1,15 +0,0 @@
package haproxy;
// All supported health check values for HAproxy.
// See https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.2-agent-check
type HealthCheckStatus string
const (
HealthCheckUp = "up"
HealthCheckDown = "down"
HealthCheckMaint = "maint"
HealthCheckReady = "ready"
HealthCheckDrain = "drain"
HealthCheckFailed = "failed"
HealthCheckStopped = "Stopped"
)

View file

@ -0,0 +1,72 @@
package api
import (
"context"
"fmt"
"github.com/eosswedenorg-go/haproxy/agentcheck"
"github.com/eosswedenorg-go/leapapi"
"github.com/eosswedenorg/antelope-api-healthcheck/internal/utils"
)
type AntelopeV1 struct {
utils.Time
client leapapi.Client
block_time float64
}
func AntelopeV1Factory(args ApiArguments) ApiInterface {
return NewAntelopeV1(args.Url, args.Host, float64(args.NumBlocks/2))
}
func NewAntelopeV1(url string, host string, block_time float64) AntelopeV1 {
api := AntelopeV1{
client: *leapapi.New(url),
block_time: block_time,
}
api.client.Host = host
return api
}
func (e AntelopeV1) LogInfo() LogParams {
p := LogParams{
"type", "antelope-v1",
"url", e.client.Url,
}
if len(e.client.Host) > 0 {
p.Add("host", e.client.Host)
}
p.Add("block_time", e.block_time)
return p
}
func (e AntelopeV1) Call(ctx context.Context) (agentcheck.Response, string) {
info, err := e.client.GetInfo(ctx)
if err != nil {
resp := agentcheck.NewStatusMessageResponse(agentcheck.Fail, "")
return resp, err.Error()
}
// Validate head block.
diff := e.GetTime().Sub(info.HeadBlockTime).Seconds()
if diff > e.block_time {
resp := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
msg := "Taking offline because head block is lagging %.0f seconds"
return resp, fmt.Sprintf(msg, diff)
} else if diff < -e.block_time {
resp := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
msg := "Taking offline because head block is %.0f seconds into the future"
return resp, fmt.Sprintf(msg, diff)
}
return agentcheck.NewStatusResponse(agentcheck.Up), "OK"
}

View file

@ -0,0 +1,171 @@
package api
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/eosswedenorg-go/haproxy/agentcheck"
"github.com/stretchr/testify/assert"
)
func TestAntelopeV1_Factory(t *testing.T) {
api := AntelopeV1Factory(ApiArguments{
Url: "https://api.v1.example.com",
Host: "host.example.com",
NumBlocks: 120,
})
expected := NewAntelopeV1("https://api.v1.example.com", "host.example.com", 60)
assert.IsType(t, expected, api)
assert.Equal(t, expected.client.Url, api.(AntelopeV1).client.Url)
assert.Equal(t, expected.client.Host, api.(AntelopeV1).client.Host)
assert.Equal(t, expected.block_time, api.(AntelopeV1).block_time)
}
func TestAntelopeV1_LogInfo(t *testing.T) {
api := NewAntelopeV1("https://api.v1.example.com", "host.example.com", 120)
expected := LogParams{"type", "antelope-v1", "url", "https://api.v1.example.com", "host", "host.example.com", "block_time", float64(120)}
assert.Equal(t, expected, api.LogInfo())
}
func TestAntelopeV1_SetTime(t *testing.T) {
expected := time.Date(2022, 2, 24, 13, 38, 0, 0, time.UTC)
api := NewAntelopeV1("", "", 60)
// Assert that time is NOW (+-10 seconds)
assert.InDelta(t, api.GetTime().Unix(), time.Now().In(time.UTC).Unix(), float64(10))
api.SetTime(expected)
assert.Equal(t, expected, api.GetTime())
}
func TestAntelopeV1_JsonFailure(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
_, err := res.Write([]byte(`!//{invalid-json}!##`))
assert.NoError(t, err)
}))
api := NewAntelopeV1(srv.URL, "", 120)
check, _ := api.Call(context.Background())
expected := agentcheck.NewStatusMessageResponse(agentcheck.Fail, "")
assert.Equal(t, expected, check)
}
func TestAntelopeV1_HTTP500Failed(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(500)
_, err := res.Write([]byte(`{}`))
assert.NoError(t, err)
}))
api := NewAntelopeV1(srv.URL, "", 120)
check, status := api.Call(context.Background())
assert.Equal(t, "server returned HTTP 500 Internal Server Error", status)
expected := agentcheck.NewStatusMessageResponse(agentcheck.Fail, "")
assert.Equal(t, expected, check)
}
func TestAntelopeV1_LaggingUp(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/v1/chain/get_info" {
info := `{
"server_version": "8f613ec9",
"head_block_num": 7272812,
"head_block_time": "2022-02-24T13:37:00"
}`
_, err := res.Write([]byte(info))
assert.NoError(t, err)
}
}))
api := NewAntelopeV1(srv.URL, "", 60)
api.SetTime(time.Date(2022, 2, 24, 13, 38, 0, 0, time.UTC))
check, status := api.Call(context.Background())
assert.Equal(t, "OK", status)
expected := agentcheck.NewStatusResponse(agentcheck.Up)
assert.Equal(t, expected, check)
}
func TestAntelopeV1_LaggingDown(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/v1/chain/get_info" {
info := `{
"server_version": "9a607cce",
"head_block_num": 87263,
"head_block_time": "2018-01-01T13:37:01"
}`
_, err := res.Write([]byte(info))
assert.NoError(t, err)
}
}))
api := NewAntelopeV1(srv.URL, "", 60)
api.SetTime(time.Date(2018, time.January, 1, 13, 38, 2, 0, time.UTC))
check, status := api.Call(context.Background())
assert.Equal(t, "Taking offline because head block is lagging 61 seconds", status)
expected := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
assert.Equal(t, expected, check)
}
func TestAntelopeV1_TimeInFutureUP(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/v1/chain/get_info" {
info := `{
"server_version": "d1bec8d3",
"head_block_num": 548847,
"head_block_time": "2020-09-22T09:32:00"
}`
_, err := res.Write([]byte(info))
assert.NoError(t, err)
}
}))
api := NewAntelopeV1(srv.URL, "", 120)
api.SetTime(time.Date(2020, 9, 22, 9, 30, 0, 0, time.UTC))
check, status := api.Call(context.Background())
assert.Equal(t, "OK", status)
expected := agentcheck.NewStatusResponse(agentcheck.Up)
assert.Equal(t, expected, check)
}
func TestAntelopeV1_TimeInFutureDown(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/v1/chain/get_info" {
info := `{
"server_version": "c879d231",
"head_block_num": 2637621,
"head_block_time": "2019-04-14T12:02:01"
}`
_, err := res.Write([]byte(info))
assert.NoError(t, err)
}
}))
api := NewAntelopeV1(srv.URL, "", 120)
api.SetTime(time.Date(2019, time.April, 14, 12, 0, 0, 0, time.UTC))
check, status := api.Call(context.Background())
assert.Equal(t, "Taking offline because head block is -121 seconds into the future", status)
expected := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
assert.Equal(t, expected, check)
}

View file

@ -0,0 +1,85 @@
package api
import (
"context"
"fmt"
"github.com/eosswedenorg-go/haproxy/agentcheck"
"github.com/eosswedenorg-go/leapapi"
"github.com/eosswedenorg/antelope-api-healthcheck/internal/utils"
)
type AntelopeV2 struct {
client leapapi.Client
offset int64
}
func AntelopeV2Factory(args ApiArguments) ApiInterface {
return NewAntelopeV2(args.Url, args.Host, int64(args.NumBlocks))
}
func NewAntelopeV2(url string, host string, offset int64) AntelopeV2 {
api := AntelopeV2{
client: *leapapi.New(url),
offset: offset,
}
api.client.Host = host
return api
}
func (e AntelopeV2) LogInfo() LogParams {
p := LogParams{
"type", "antelope-v2",
"url", e.client.Url,
}
if len(e.client.Host) > 0 {
p.Add("host", e.client.Host)
}
p.Add("offset", e.offset)
return p
}
func (e AntelopeV2) Call(ctx context.Context) (agentcheck.Response, string) {
health, err := e.client.GetHealth(ctx)
if err != nil {
resp := agentcheck.NewStatusMessageResponse(agentcheck.Fail, "")
return resp, err.Error()
}
// Fetch elasticsearch and nodeos block numbers from json.
var es_block int64 = 0
var node_block int64 = 0
for _, v := range health.Health {
if v.Name == "Elasticsearch" {
es_block = utils.JsonGetInt64(v.Data["last_indexed_block"])
} else if v.Name == "NodeosRPC" {
node_block = utils.JsonGetInt64(v.Data["head_block_num"])
}
}
// Error out if ether or both are zero.
if es_block == 0 || node_block == 0 {
msg := fmt.Sprintf("Failed to get Elasticsearch and/or nodeos "+
"block numbers (es: %d, eos: %d)", es_block, node_block)
resp := agentcheck.NewStatusMessageResponse(agentcheck.Fail, "")
return resp, msg
}
// Check if ES is behind or in the future.
diff := node_block - es_block
if diff > e.offset {
resp := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
return resp, fmt.Sprintf("Taking offline because Elastic is %d blocks behind", diff)
} else if diff < -e.offset {
resp := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
return resp, fmt.Sprintf("Taking offline because Elastic is %d blocks into the future", -1*diff)
}
return agentcheck.NewStatusResponse(agentcheck.Up), "OK"
}

View file

@ -0,0 +1,382 @@
package api
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"github.com/eosswedenorg-go/haproxy/agentcheck"
"github.com/stretchr/testify/assert"
)
func TestAntelopeV2_Factory(t *testing.T) {
api := AntelopeV2Factory(ApiArguments{
Url: "https://api.v2.example.com",
Host: "host.example.com",
NumBlocks: 120,
})
expected := NewAntelopeV2("https://api.v2.example.com", "host.example.com", 120)
assert.IsType(t, expected, api)
assert.Equal(t, expected.client.Url, api.(AntelopeV2).client.Url)
assert.Equal(t, expected.client.Host, api.(AntelopeV2).client.Host)
assert.Equal(t, expected.offset, api.(AntelopeV2).offset)
}
func TestAntelopeV2_LogInfo(t *testing.T) {
api := NewAntelopeV2("https://api.v2.example.com", "host.example.com", 120)
expected := LogParams{"type", "antelope-v2", "url", "https://api.v2.example.com", "host", "host.example.com", "offset", int64(120)}
assert.Equal(t, expected, api.LogInfo())
}
func TestAntelopeV2_JsonFailure(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
_, err := res.Write([]byte(`!//{invalid-json}!##`))
assert.NoError(t, err)
}))
api := NewAntelopeV2(srv.URL, "", 120)
check, _ := api.Call(context.Background())
expected := agentcheck.NewStatusMessageResponse(agentcheck.Fail, "")
assert.Equal(t, expected, check)
}
func TestAntelopeV2_HTTP500Failed(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(500)
_, err := res.Write([]byte(`{}`))
assert.NoError(t, err)
}))
api := NewAntelopeV2(srv.URL, "", 120)
check, status := api.Call(context.Background())
assert.Equal(t, "server returned HTTP 500 Internal Server Error", status)
expected := agentcheck.NewStatusMessageResponse(agentcheck.Fail, "")
assert.Equal(t, expected, check)
}
func TestAntelopeV2_LaggingUp(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/v2/health" {
info := `{
"version": "1.0",
"version_hash": "028d5a34463884fcbe2ecfd3c0fcb3b5d4d538f4fd64803c1ef7209c85f2f266",
"host": "api.test.com:443",
"health": [
{
"service": "NodeosRPC",
"status": "OK",
"service_data": {
"head_block_num": 263148621,
"head_block_time": "2022-08-17T14:16:36.000",
"time_offset": 190,
"last_irreversible_block": 263148296,
"chain_id": "f8c74ccb7f9dea6f26a6d7f786809ddd1bce9fada3867f567dd83691b5348534"
},
"time": 1642174781678
},
{
"service": "Elasticsearch",
"status": "OK",
"service_data": {
"last_indexed_block": 263148121,
"total_indexed_blocks": 263148121,
"active_shards": "100.0%"
},
"time": 1642174781736
}
]
}`
_, err := res.Write([]byte(info))
assert.NoError(t, err)
}
}))
api := NewAntelopeV2(srv.URL, "", 500)
check, status := api.Call(context.Background())
assert.Equal(t, "OK", status)
expected := agentcheck.NewStatusResponse(agentcheck.Up)
assert.Equal(t, expected, check)
}
func TestAntelopeV2_LaggingDown(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/v2/health" {
info := `{
"version": "1.0",
"version_hash": "028d5a34463884fcbe2ecfd3c0fcb3b5d4d538f4fd64803c1ef7209c85f2f266",
"host": "api.test.com:443",
"health": [
{
"service": "NodeosRPC",
"status": "OK",
"service_data": {
"head_block_num": 263148621,
"head_block_time": "2022-08-17T14:16:36.000",
"time_offset": 190,
"last_irreversible_block": 263148296,
"chain_id": "f8c74ccb7f9dea6f26a6d7f786809ddd1bce9fada3867f567dd83691b5348534"
},
"time": 1642174781678
},
{
"service": "Elasticsearch",
"status": "OK",
"service_data": {
"last_indexed_block": 263148121,
"total_indexed_blocks": 263148121,
"active_shards": "100.0%"
},
"time": 1642174781736
}
]
}`
_, err := res.Write([]byte(info))
assert.NoError(t, err)
}
}))
api := NewAntelopeV2(srv.URL, "", 499)
check, status := api.Call(context.Background())
assert.Equal(t, "Taking offline because Elastic is 500 blocks behind", status)
expected := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
assert.Equal(t, expected, check)
}
func TestAntelopeV2_LaggingESInFutureUP(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/v2/health" {
info := `{
"version": "1.0",
"version_hash": "028d5a34463884fcbe2ecfd3c0fcb3b5d4d538f4fd64803c1ef7209c85f2f266",
"host": "api.test.com:443",
"health": [
{
"service": "NodeosRPC",
"status": "OK",
"service_data": {
"head_block_num": 263148621,
"head_block_time": "2022-08-17T14:16:36.000",
"time_offset": 190,
"last_irreversible_block": 263148296,
"chain_id": "f8c74ccb7f9dea6f26a6d7f786809ddd1bce9fada3867f567dd83691b5348534"
},
"time": 1642174781678
},
{
"service": "Elasticsearch",
"status": "OK",
"service_data": {
"last_indexed_block": 263148821,
"total_indexed_blocks": 263148821,
"active_shards": "100.0%"
},
"time": 1642174781736
}
]
}`
_, err := res.Write([]byte(info))
assert.NoError(t, err)
}
}))
api := NewAntelopeV2(srv.URL, "", 200)
check, status := api.Call(context.Background())
assert.Equal(t, "OK", status)
expected := agentcheck.NewStatusResponse(agentcheck.Up)
assert.Equal(t, expected, check)
}
func TestAntelopeV2_LaggingESInFutureDown(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/v2/health" {
info := `{
"version": "1.0",
"version_hash": "028d5a34463884fcbe2ecfd3c0fcb3b5d4d538f4fd64803c1ef7209c85f2f266",
"host": "api.test.com:443",
"health": [
{
"service": "NodeosRPC",
"status": "OK",
"service_data": {
"head_block_num": 263148621,
"head_block_time": "2022-08-17T14:16:36.000",
"time_offset": 190,
"last_irreversible_block": 263148296,
"chain_id": "f8c74ccb7f9dea6f26a6d7f786809ddd1bce9fada3867f567dd83691b5348534"
},
"time": 1642174781678
},
{
"service": "Elasticsearch",
"status": "OK",
"service_data": {
"last_indexed_block": 263148822,
"total_indexed_blocks": 263148822,
"active_shards": "100.0%"
},
"time": 1642174781736
}
]
}`
_, err := res.Write([]byte(info))
assert.NoError(t, err)
}
}))
api := NewAntelopeV2(srv.URL, "", 200)
check, status := api.Call(context.Background())
assert.Equal(t, "Taking offline because Elastic is 201 blocks into the future", status)
expected := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
assert.Equal(t, expected, check)
}
func TestAntelopeV2_ElasticsFailed(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/v2/health" {
info := `{
"version": "1.0",
"version_hash": "028d5a34463884fcbe2ecfd3c0fcb3b5d4d538f4fd64803c1ef7209c85f2f266",
"host": "api.test.com:443",
"health": [
{
"service": "NodeosRPC",
"status": "OK",
"service_data": {
"head_block_num": 263148621,
"head_block_time": "2022-08-17T14:16:36.000",
"time_offset": 190,
"last_irreversible_block": 263148296,
"chain_id": "f8c74ccb7f9dea6f26a6d7f786809ddd1bce9fada3867f567dd83691b5348534"
},
"time": 1660745796190
},
{
"service": "Elasticsearch",
"status": "DOWN",
"service_data": {
"last_indexed_block": 0,
"total_indexed_blocks": 0,
"active_shards": "0.0%"
},
"time": 1660745796204
}
]
}`
_, err := res.Write([]byte(info))
assert.NoError(t, err)
}
}))
api := NewAntelopeV2(srv.URL, "", 500)
check, status := api.Call(context.Background())
assert.Equal(t, "Failed to get Elasticsearch and/or nodeos block numbers (es: 0, eos: 263148621)", status)
expected := agentcheck.NewStatusMessageResponse(agentcheck.Fail, "")
assert.Equal(t, expected, check)
}
func TestAntelopeV2_NodeosRPCFailed(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/v2/health" {
info := `{
"version": "1.0",
"version_hash": "028d5a34463884fcbe2ecfd3c0fcb3b5d4d538f4fd64803c1ef7209c85f2f266",
"host": "api.test.com:443",
"health": [
{
"service": "NodeosRPC",
"status": "DOWN",
"service_data": {
"head_block_num": 0,
"head_block_time": "",
"time_offset": 0,
"last_irreversible_block": 0,
"chain_id": ""
},
"time": 1642174781678
},
{
"service": "Elasticsearch",
"status": "DOWN",
"service_data": {
"last_indexed_block": 263148121,
"total_indexed_blocks": 263148121,
"active_shards": "100.0%"
},
"time": 1642174781736
}
]
}`
_, err := res.Write([]byte(info))
assert.NoError(t, err)
}
}))
api := NewAntelopeV2(srv.URL, "", 500)
check, status := api.Call(context.Background())
assert.Equal(t, "Failed to get Elasticsearch and/or nodeos block numbers (es: 263148121, eos: 0)", status)
expected := agentcheck.NewStatusMessageResponse(agentcheck.Fail, "")
assert.Equal(t, expected, check)
}
func TestAntelopeV2_ElasticsNodeosRPCFailed(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/v2/health" {
info := `{
"version": "1.0",
"version_hash": "028d5a34463884fcbe2ecfd3c0fcb3b5d4d538f4fd64803c1ef7209c85f2f266",
"host": "api.test.com:443",
"health": [
{
"service": "NodeosRPC",
"status": "DOWN",
"service_data": {},
"time": 1642174781678
},
{
"service": "Elasticsearch",
"status": "DOWN",
"service_data": {},
"time": 1642174781736
}
]
}`
_, err := res.Write([]byte(info))
assert.NoError(t, err)
}
}))
api := NewAntelopeV2(srv.URL, "", 500)
check, status := api.Call(context.Background())
assert.Equal(t, "Failed to get Elasticsearch and/or nodeos block numbers (es: 0, eos: 0)", status)
expected := agentcheck.NewStatusMessageResponse(agentcheck.Fail, "")
assert.Equal(t, expected, check)
}

View file

@ -0,0 +1,91 @@
package api
import (
"context"
"fmt"
"github.com/eosswedenorg-go/atomicasset"
"github.com/eosswedenorg-go/haproxy/agentcheck"
"github.com/eosswedenorg/antelope-api-healthcheck/internal/utils"
)
type AtomicAsset struct {
utils.Time
url string
host string
block_time float64
}
func AtomicAssetFactory(args ApiArguments) ApiInterface {
return NewAtomicAsset(args.Url, args.Host, float64(args.NumBlocks/2))
}
func NewAtomicAsset(url string, host string, block_time float64) AtomicAsset {
return AtomicAsset{
url: url,
host: host,
block_time: block_time,
}
}
func (e AtomicAsset) LogInfo() LogParams {
p := LogParams{
"type", "atomicasset",
"url", e.url,
"block_time", e.block_time,
}
if len(e.host) > 0 {
p.Add("host", e.host)
}
return p
}
func (e AtomicAsset) Call(ctx context.Context) (agentcheck.Response, string) {
client := atomicasset.NewWithContext(e.url, ctx)
client.Host = e.host
h, err := client.GetHealth()
if err != nil {
resp := agentcheck.NewStatusMessageResponse(agentcheck.Fail, "")
return resp, err.Error()
}
// Check HTTP Status Code
if h.HTTPStatusCode > 299 {
resp := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
msg := "Taking offline because %v was received from backend"
return resp, fmt.Sprintf(msg, h.HTTPStatusCode)
}
// Check postgres
if h.Data.Postgres.Status != "OK" {
resp := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
msg := "Taking offline because Postgres reported '%s'"
return resp, fmt.Sprintf(msg, h.Data.Postgres.Status)
}
// Check redis
if h.Data.Redis.Status != "OK" {
resp := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
msg := "Taking offline because Redis reported '%s'"
return resp, fmt.Sprintf(msg, h.Data.Redis.Status)
}
// Validate head block.
diff := e.GetTime().Sub(h.Data.Chain.HeadTime.Time()).Seconds()
if diff > e.block_time {
resp := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
msg := "Taking offline because head block is lagging %.0f seconds"
return resp, fmt.Sprintf(msg, diff)
} else if diff < -e.block_time {
resp := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
msg := "Taking offline because head block is %.0f seconds into the future"
return resp, fmt.Sprintf(msg, diff)
}
return agentcheck.NewStatusResponse(agentcheck.Up), "OK"
}

View file

@ -0,0 +1,316 @@
package api
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/eosswedenorg-go/haproxy/agentcheck"
"github.com/stretchr/testify/assert"
)
func TestAtomicAsset_Factory(t *testing.T) {
api := AtomicAssetFactory(ApiArguments{
Url: "https://atomic.example.com",
NumBlocks: 120,
})
expected := NewAtomicAsset("https://atomic.example.com", "", 60)
assert.IsType(t, expected, api)
assert.Equal(t, expected.url, api.(AtomicAsset).url)
assert.Equal(t, expected.block_time, api.(AtomicAsset).block_time)
}
func TestAtomicAsset_LogInfo(t *testing.T) {
api := NewAtomicAsset("https://atomic.example.com", "", 120)
expected := LogParams{"type", "atomicasset", "url", "https://atomic.example.com", "block_time", float64(120)}
assert.Equal(t, expected, api.LogInfo())
}
func TestAtomicAsset_LogInfoWithHost(t *testing.T) {
api := NewAtomicAsset("https://atomic.example.com", "some.other.host", 120)
expected := LogParams{"type", "atomicasset", "url", "https://atomic.example.com", "block_time", float64(120), "host", "some.other.host"}
assert.Equal(t, expected, api.LogInfo())
}
func TestAtomicAsset_SetTime(t *testing.T) {
expected := time.Date(2019, 3, 18, 20, 29, 32, 0, time.UTC)
api := NewAtomicAsset("", "", 60)
// Assert that time is NOW (+-10 seconds)
assert.InDelta(t, api.GetTime().Unix(), time.Now().In(time.UTC).Unix(), float64(10))
api.SetTime(expected)
assert.Equal(t, expected, api.GetTime())
}
func TestAtomicAsset_JsonFailure(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
_, err := res.Write([]byte(`!//{invalid-json}!##`))
assert.NoError(t, err)
}))
api := NewAtomicAsset(srv.URL, "", 120)
check, _ := api.Call(context.Background())
expected := agentcheck.NewStatusMessageResponse(agentcheck.Fail, "")
assert.Equal(t, expected, check)
}
func TestAtomicAsset_HTTP500Down(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
res.Header().Add("Content-type", "application/json; charset=utf-8")
res.WriteHeader(500)
_, err := res.Write([]byte(`{}`))
assert.NoError(t, err)
}))
api := NewAtomicAsset(srv.URL, "", 120)
check, status := api.Call(context.Background())
assert.Equal(t, "Taking offline because 500 was received from backend", status)
expected := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
assert.Equal(t, expected, check)
}
func TestAtomicAsset_LaggingUp(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/health" {
payload := `{
"success":true,
"data":{
"version":"1.0.0",
"postgres":{
"status":"OK"
},
"redis":{
"status":"OK"
},
"chain":{
"status":"OK",
"head_block":2173612361,
"head_time":1759953927000
}
},
"query_time":1759953929542
}`
res.Header().Add("Content-type", "application/json; charset=utf-8")
_, err := res.Write([]byte(payload))
assert.NoError(t, err)
}
}))
api := NewAtomicAsset(srv.URL, "", 120)
api.SetTime(time.Date(2025, 10, 8, 20, 7, 27, 0, time.UTC))
check, status := api.Call(context.Background())
assert.Equal(t, "OK", status)
expected := agentcheck.NewStatusResponse(agentcheck.Up)
assert.Equal(t, expected, check)
}
func TestAtomicAsset_LaggingDown(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/health" {
payload := `{
"success":true,
"data":{
"version":"1.0.0",
"postgres":{
"status":"OK"
},
"redis":{
"status":"OK"
},
"chain":{
"status":"OK",
"head_block":213671263812,
"head_time":1533451894000
}
},
"query_time":1533451895542
}`
res.Header().Add("Content-type", "application/json; charset=utf-8")
_, err := res.Write([]byte(payload))
assert.NoError(t, err)
}
}))
api := NewAtomicAsset(srv.URL, "", 120)
api.SetTime(time.Date(2018, 8, 5, 6, 53, 35, 0, time.UTC))
check, status := api.Call(context.Background())
assert.Equal(t, "Taking offline because head block is lagging 121 seconds", status)
expected := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
assert.Equal(t, expected, check)
}
func TestAtomicAsset_InFutureUp(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/health" {
payload := `{
"success":true,
"data":{
"version":"1.0.0",
"postgres":{
"status":"OK"
},
"redis":{
"status":"OK"
},
"chain":{
"status":"OK",
"head_block":213671263812,
"head_time":1728954676500
}
},
"query_time":1728954678231
}`
res.Header().Add("Content-type", "application/json; charset=utf-8")
_, err := res.Write([]byte(payload))
assert.NoError(t, err)
}
}))
api := NewAtomicAsset(srv.URL, "", 120)
api.SetTime(time.Date(2024, 10, 15, 1, 9, 16, 500*int(time.Millisecond), time.UTC))
check, status := api.Call(context.Background())
assert.Equal(t, "OK", status)
expected := agentcheck.NewStatusResponse(agentcheck.Up)
assert.Equal(t, expected, check)
}
func TestAtomicAsset_InFutureDown(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/health" {
payload := `{
"success":true,
"data":{
"version":"1.0.0",
"postgres":{
"status":"OK"
},
"redis":{
"status":"OK"
},
"chain":{
"status":"OK",
"head_block":213671263812,
"head_time":1041122824500
}
},
"query_time":1041122832231
}`
res.Header().Add("Content-type", "application/json; charset=utf-8")
_, err := res.Write([]byte(payload))
assert.NoError(t, err)
}
}))
api := NewAtomicAsset(srv.URL, "", 120)
api.SetTime(time.Date(2002, 12, 29, 0, 45, 3, 500*int(time.Millisecond), time.UTC))
check, status := api.Call(context.Background())
assert.Equal(t, "Taking offline because head block is -121 seconds into the future", status)
expected := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
assert.Equal(t, expected, check)
}
func TestAtomicAsset_RedisDown(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/health" {
payload := `{
"success":true,
"data":{
"version":"1.0.0",
"postgres":{
"status":"OK"
},
"redis":{
"status":"DOWN"
},
"chain":{
"status":"OK",
"head_block":213671263812,
"head_time":1426072770500
}
},
"query_time":1426072775872
}`
res.Header().Add("Content-type", "application/json; charset=utf-8")
_, err := res.Write([]byte(payload))
assert.NoError(t, err)
}
}))
api := NewAtomicAsset(srv.URL, "", 120)
api.SetTime(time.Date(2015, 3, 11, 11, 19, 30, 500*int(time.Millisecond), time.UTC))
check, status := api.Call(context.Background())
assert.Equal(t, "Taking offline because Redis reported 'DOWN'", status)
expected := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
assert.Equal(t, expected, check)
}
func TestAtomicAsset_PostgresDown(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
if req.URL.String() == "/health" {
payload := `{
"success":true,
"data":{
"version":"1.0.0",
"postgres":{
"status":"DOWN"
},
"redis":{
"status":"OK"
},
"chain":{
"status":"OK",
"head_block":213671263812,
"head_time":1562868371500
}
},
"query_time":156286837143
}`
res.Header().Add("Content-type", "application/json; charset=utf-8")
_, err := res.Write([]byte(payload))
assert.NoError(t, err)
}
}))
api := NewAtomicAsset(srv.URL, "", 120)
api.SetTime(time.Date(2019, 7, 11, 18, 6, 11, 500*int(time.Millisecond), time.UTC))
check, status := api.Call(context.Background())
assert.Equal(t, "Taking offline because Postgres reported 'DOWN'", status)
expected := agentcheck.NewStatusMessageResponse(agentcheck.Down, "")
assert.Equal(t, expected, check)
}

47
internal/api/debug.go Normal file
View file

@ -0,0 +1,47 @@
package api
import (
"context"
"strings"
"github.com/eosswedenorg-go/haproxy/agentcheck"
)
type DebugApi struct {
response agentcheck.Response
}
func parseResponse(resp string) agentcheck.Response {
parts := strings.SplitN(resp, "#", 2)
// Status with message
if len(parts) > 1 {
rtype := agentcheck.StatusMessageResponseType(parts[0])
return agentcheck.NewStatusMessageResponse(rtype, parts[1])
}
// Only status.
rtype := agentcheck.StatusResponseType(resp)
return agentcheck.NewStatusResponse(rtype)
}
func DebugApiFactory(args ApiArguments) ApiInterface {
return NewDebugApi(args.Url)
}
func NewDebugApi(response string) DebugApi {
return DebugApi{
response: parseResponse(response),
}
}
func (d DebugApi) LogInfo() LogParams {
return LogParams{
"type", "Debug",
"response", strings.TrimSpace(d.response.String()),
}
}
func (d DebugApi) Call(_ context.Context) (agentcheck.Response, string) {
return d.response, ""
}

View file

@ -0,0 +1,67 @@
package api
import (
"context"
"reflect"
"testing"
"github.com/eosswedenorg-go/haproxy/agentcheck"
"github.com/stretchr/testify/assert"
)
func TestDebugApi_Factory(t *testing.T) {
api := DebugApiFactory(ApiArguments{
Url: "up",
Host: "host",
NumBlocks: 40,
})
assert.IsType(t, DebugApi{}, api)
assert.Equal(t, api.(DebugApi).response, agentcheck.NewStatusResponse(agentcheck.Up))
}
func TestNewDebugApi(t *testing.T) {
type args struct {
response string
}
tests := []struct {
name string
args args
want DebugApi
}{
{"Up", args{"up"}, DebugApi{response: agentcheck.NewStatusResponse(agentcheck.Up)}},
{"Down", args{"down"}, DebugApi{response: agentcheck.NewStatusResponse("down")}},
{"DownMessage", args{"down#some message"}, DebugApi{response: agentcheck.NewStatusMessageResponse(agentcheck.Down, "some message")}},
{"Ready", args{"ready"}, DebugApi{response: agentcheck.NewStatusResponse(agentcheck.Ready)}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := NewDebugApi(tt.args.response); !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewDebugApi() = %v, want %v", got, tt.want)
}
})
}
}
func TestDebugApi_LogInfo(t *testing.T) {
expected := LogParams{"type", "Debug", "response", "up"}
api := DebugApi{
response: agentcheck.NewStatusResponse(agentcheck.Up),
}
assert.Equal(t, api.LogInfo(), expected)
}
func TestDebugApi_Call(t *testing.T) {
expected := agentcheck.NewStatusMessageResponse(agentcheck.Stopped, "message")
api := DebugApi{
response: expected,
}
response, msg := api.Call(context.Background())
assert.Equal(t, response, expected)
assert.Equal(t, msg, "")
}

33
internal/api/interface.go Normal file
View file

@ -0,0 +1,33 @@
package api
import (
"context"
"github.com/eosswedenorg-go/haproxy/agentcheck"
)
/**
* Generic struct that is passed to factory functions
* to configure the API request.
*/
type ApiArguments struct {
Url string
Host string
NumBlocks int
}
/**
* Factory function
*
* Each API must implement this function and process `args`
* returing a instance of it's implementation of the ApiInterface
*/
type Factory func(args ApiArguments) ApiInterface
type ApiInterface interface {
// Returns Logging information
LogInfo() LogParams
// Call api and validate it's status.
Call(ctx context.Context) (agentcheck.Response, string)
}

View file

@ -0,0 +1,13 @@
package api
type LogParams []interface{}
func (p *LogParams) Add(field string, value interface{}) {
*p = append(*p, field, value)
}
// Syntactic sugar for append(p, other...)
// Returns a new instance of LogParams with all values from both p and other
func (p LogParams) Combine(other LogParams) LogParams {
return append(p, other...)
}

View file

@ -0,0 +1,47 @@
package api
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestLogParams(t *testing.T) {
type test_struct struct {
First string
Second int
}
p := LogParams{}
p.Add("one", 1)
p.Add("string", "str")
p.Add("struct", test_struct{First: "first_string", Second: 1234})
expected := []interface{}([]interface{}{
"one", 1,
"string", "str",
"struct",
test_struct{
First: "first_string",
Second: 1234,
},
})
assert.ElementsMatch(t, expected, p)
}
func TestLogParams_Combine(t *testing.T) {
a := LogParams{"one", 1, "string1", "str1"}
b := LogParams{"two", 2, "string2", "str2"}
expected := LogParams{
"one", 1,
"string1", "str1",
"two", 2,
"string2", "str2",
}
assert.Equal(t, expected, a.Combine(b))
}

20
internal/api/make.go Normal file
View file

@ -0,0 +1,20 @@
package api
import (
"fmt"
)
func Make(name string, args ApiArguments) (ApiInterface, error) {
factories := map[string]Factory{
"v1": AntelopeV1Factory,
"v2": AntelopeV2Factory,
"atomic": AtomicAssetFactory,
"debug": DebugApiFactory,
}
if factory, ok := factories[name]; ok {
return factory(args), nil
}
return nil, fmt.Errorf("invalid API '%s'", name)
}

37
internal/api/make_test.go Normal file
View file

@ -0,0 +1,37 @@
package api
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestMakeV1(t *testing.T) {
api, err := Make("v1", ApiArguments{})
assert.NoError(t, err)
assert.IsType(t, AntelopeV1{}, api)
}
func TestMakeV2(t *testing.T) {
api, err := Make("v2", ApiArguments{})
assert.NoError(t, err)
assert.IsType(t, AntelopeV2{}, api)
}
func TestMakeAtomic(t *testing.T) {
api, err := Make("atomic", ApiArguments{})
assert.NoError(t, err)
assert.IsType(t, AtomicAsset{}, api)
}
func TestMakeDebug(t *testing.T) {
api, err := Make("debug", ApiArguments{})
assert.NoError(t, err)
assert.IsType(t, DebugApi{}, api)
}
func TestMakeInvalid(t *testing.T) {
api, err := Make("invalid", ApiArguments{})
assert.Error(t, err)
assert.Nil(t, api)
}

View file

@ -0,0 +1,45 @@
package server
import (
"fmt"
"strconv"
"strings"
"github.com/eosswedenorg/antelope-api-healthcheck/internal/api"
)
func ParseArguments(args []string) api.ApiArguments {
a := api.ApiArguments{
NumBlocks: 10,
}
// 1. url (scheme + ip/domain + port)
a.Url = args[0]
// 2. num blocks
if len(args) > 1 {
num, err := strconv.ParseInt(args[1], 10, 32)
if err == nil {
a.NumBlocks = int(num)
}
}
// 3. Host
if len(args) > 2 {
a.Host = args[2]
}
return a
}
func ParseRequest(request string) (api.ApiInterface, error) {
p := strings.Split(strings.TrimSpace(request), "|")
if len(p) < 2 {
return nil, fmt.Errorf("invalid number of parameters in agent request")
}
a := ParseArguments(p[1:])
return api.Make(p[0], a)
}

View file

@ -0,0 +1,112 @@
package server
import (
"testing"
"github.com/eosswedenorg/antelope-api-healthcheck/internal/api"
"github.com/stretchr/testify/assert"
)
func TestParseRequest_WithInvalidApi(t *testing.T) {
api, err := ParseRequest("invalid|http://api.example.com")
assert.Error(t, err)
assert.Equal(t, err.Error(), "invalid API 'invalid'")
assert.Nil(t, api)
}
func TestParseRequest_WithInvalidParams(t *testing.T) {
api, err := ParseRequest("v1")
assert.Error(t, err)
assert.Equal(t, err.Error(), "invalid number of parameters in agent request")
assert.Nil(t, api)
}
// AntelopeV1
// --------------------------------
func TestParseRequest_AntelopeV1(t *testing.T) {
expected := api.NewAntelopeV1("http://api.example.com", "", 5)
api, err := ParseRequest("v1|http://api.example.com")
assert.NoError(t, err)
assert.Equal(t, expected.LogInfo(), api.LogInfo())
}
func TestParseRequest_AntelopeV1WithBlockNumber(t *testing.T) {
expected := api.NewAntelopeV1("http://api.example.com", "", 1000)
api, err := ParseRequest("v1|http://api.example.com|2000")
assert.NoError(t, err)
assert.Equal(t, expected.LogInfo(), api.LogInfo())
}
func TestParseRequest_AntelopeV1Full(t *testing.T) {
expected := api.NewAntelopeV1("http://api.example.com", "http://host.example.com", 500)
api, err := ParseRequest("v1|http://api.example.com|1000|http://host.example.com")
assert.NoError(t, err)
assert.Equal(t, expected.LogInfo(), api.LogInfo())
}
// AntelopeV2
// --------------------------------
func TestParseRequest_AntelopeV2(t *testing.T) {
expected := api.NewAntelopeV2("http://api.v2.example.com", "", 10)
api, err := ParseRequest("v2|http://api.v2.example.com")
assert.NoError(t, err)
assert.Equal(t, expected.LogInfo(), api.LogInfo())
}
func TestParseRequest_AntelopeV2WithOffset(t *testing.T) {
expected := api.NewAntelopeV2("http://api.v2.example.com", "", 1000)
api, err := ParseRequest("v2|http://api.v2.example.com|1000")
assert.NoError(t, err)
assert.Equal(t, expected.LogInfo(), api.LogInfo())
}
func TestParseRequest_AntelopeV2Full(t *testing.T) {
expected := api.NewAntelopeV2("http://api.v2.example.com", "http://host.example.com", 1000)
api, err := ParseRequest("v2|http://api.v2.example.com|1000|http://host.example.com")
assert.NoError(t, err)
assert.Equal(t, expected.LogInfo(), api.LogInfo())
}
// AtomicAsset
// --------------------------------
func TestParseRequest_AtomicAsset(t *testing.T) {
expected := api.NewAtomicAsset("http://api.atomicassets.io", "", 5)
api, err := ParseRequest("atomic|http://api.atomicassets.io")
assert.NoError(t, err)
assert.Equal(t, expected.LogInfo(), api.LogInfo())
}
func TestParseRequest_AtomicAssetWithBlockTime(t *testing.T) {
expected := api.NewAtomicAsset("http://api.atomicassets.io", "", 256)
api, err := ParseRequest("atomic|http://api.atomicassets.io|512")
assert.NoError(t, err)
assert.Equal(t, expected.LogInfo(), api.LogInfo())
}
func TestParseRequest_AtomicAssetWithHost(t *testing.T) {
expected := api.NewAtomicAsset("http://api.atomicassets.io", "some.other.host", 256)
api, err := ParseRequest("atomic|http://api.atomicassets.io|512|some.other.host")
assert.NoError(t, err)
assert.Equal(t, expected.LogInfo(), api.LogInfo())
}
func TestParseRequest_DebugApi(t *testing.T) {
expected := api.NewDebugApi("some_api_call")
api, err := ParseRequest("debug|some_api_call")
assert.NoError(t, err)
assert.Equal(t, expected.LogInfo(), api.LogInfo())
}

176
internal/server/server.go Normal file
View file

@ -0,0 +1,176 @@
package server
import (
"context"
"fmt"
"strings"
"sync/atomic"
"time"
"github.com/eosswedenorg-go/haproxy/agentcheck"
"github.com/eosswedenorg/antelope-api-healthcheck/internal/api"
log "github.com/inconshreveable/log15"
"github.com/panjf2000/gnet/v2"
)
type Server struct {
gnet.BuiltinEventEngine
eng gnet.Engine
// Address to bind to.
addr string
// Number of connections between each OnTick()
num_conn uint64
// Time between each call to OnTick()
tick_interval time.Duration
// API Check timeout
timeout time.Duration
}
type Option func(*Server)
func New(addr string, options ...Option) *Server {
s := &Server{
addr: fmt.Sprintf("tcp://%s", addr),
}
for _, opt := range options {
opt(s)
}
return s
}
func WithTick(interval time.Duration) Option {
return func(s *Server) {
s.tick_interval = interval
}
}
func WithTimeout(duration time.Duration) Option {
return func(s *Server) {
s.timeout = duration
}
}
// OnBoot callback function
//
// ---------------------------------------------------------
func (s *Server) OnBoot(eng gnet.Engine) gnet.Action {
s.eng = eng
log.Info("Server started", "addr", s.addr)
return gnet.None
}
func (s *Server) OnOpen(c gnet.Conn) ([]byte, gnet.Action) {
atomic.AddUint64(&s.num_conn, 1)
return nil, gnet.None
}
// OnClose callback function
//
// ---------------------------------------------------------
func (s *Server) OnClose(c gnet.Conn, err error) gnet.Action {
if err != nil {
log.Error("TCP Close", "error", err)
}
return gnet.None
}
// OnShutdown callback function
//
// ---------------------------------------------------------
func (s *Server) OnShutdown(eng gnet.Engine) {
log.Info("Server shutdown")
}
// OnTick callback function
//
// ---------------------------------------------------------
func (s *Server) OnTick() (time.Duration, gnet.Action) {
log.Info("Server info", log.Ctx{
"connections": atomic.LoadUint64(&s.num_conn),
"current_connections": s.eng.CountConnections(),
})
atomic.StoreUint64(&s.num_conn, 0)
return s.tick_interval, gnet.None
}
// OnTraffic callback function
//
// ---------------------------------------------------------
func (s *Server) OnTraffic(c gnet.Conn) gnet.Action {
logger := log.Root()
req, err := c.Next(-1)
if err != nil {
logger.Error("Read", "message", err)
return gnet.Close
}
// Check api.
// -------------------
healthCheckApi, err := ParseRequest(string(req))
if err != nil {
logger.Warn("Agent request error", "message", err)
resp := agentcheck.NewStatusMessageResponse(agentcheck.Fail, "")
_, err = c.Write([]byte(resp.String()))
if err != nil {
logger.Error("Write", "message", err)
}
return gnet.Close
}
// gnet library does not like blocking calls.
// as we do a blocking http call here, we need to wrap it in a goroutine.
go func() {
ctx := context.Background()
if s.timeout > 0 {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, s.timeout)
defer cancel()
}
t := time.Now()
status, msg := healthCheckApi.Call(ctx)
req_time := time.Since(t)
params := api.LogParams{}
params.Add("status", strings.TrimSpace(status.String()))
params.Add("duration", req_time)
params.Add("duration_us", req_time.Microseconds())
if msg != "OK" && len(msg) > 0 {
params.Add("error", msg)
}
logger.Info("API Check", params.Combine(healthCheckApi.LogInfo())...)
// Report status to HAproxy
err = c.AsyncWrite([]byte(status.String()), func(c gnet.Conn, err error) error {
return c.Close()
})
if err != nil {
logger.Error("Write", "message", err)
}
}()
return gnet.None
}
func (s *Server) Close() error {
return s.eng.Stop(context.Background())
}
// Run the server event loop.
//
// ---------------------------------------------------------
func (s *Server) Run() error {
return gnet.Run(s, s.addr, gnet.WithMulticore(true), gnet.WithTicker(true))
}

16
internal/utils/json.go Normal file
View file

@ -0,0 +1,16 @@
package utils
// JsonGetInt64
// performs float64 (json numbers are always float64)
// type assertion and casts to int64.
//
// if the type assertion fails, the function defaults 0 (zero).
// ---------------------------------------------------------
func JsonGetInt64(input interface{}) int64 {
v, res := input.(float64)
if res {
return (int64)(v)
}
return 0
}

View file

@ -0,0 +1,22 @@
package utils
import "testing"
func TestJson_GetInt64(t *testing.T) {
tests := []struct {
name string
input interface{}
want int64
}{
{"String", "test", 0},
{"Int", 1234, 0},
{"Float", float64(1234), 1234},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := JsonGetInt64(tt.input); got != tt.want {
t.Errorf("JsonGetInt64() = %v, want %v", got, tt.want)
}
})
}
}

View file

@ -0,0 +1,18 @@
package utils
import (
log "github.com/inconshreveable/log15"
)
func ParseLogFormatter(name string) log.Format {
switch name {
case "logfmt":
return log.LogfmtFormat()
case "json":
return log.JsonFormat()
case "json-pretty":
return log.JsonFormatEx(true, true)
default:
return log.TerminalFormat()
}
}

View file

@ -0,0 +1,29 @@
package utils
import (
"reflect"
"testing"
log "github.com/inconshreveable/log15"
)
func TestParseLogFormatter(t *testing.T) {
tests := []struct {
name string
arg string
want log.Format
}{
{"Default", "", log.TerminalFormat()},
{"LogFmt", "logfmt", log.LogfmtFormat()},
{"Json", "json", log.JsonFormat()},
{"JsonPretty", "json-pretty", log.JsonFormat()},
{"Unknown", "unknown", log.TerminalFormat()},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := ParseLogFormatter(tt.arg); reflect.ValueOf(got).Pointer() != reflect.ValueOf(tt.want).Pointer() {
t.Errorf("parseLogFormatter() = %v, want %v", got, tt.want)
}
})
}
}

20
internal/utils/time.go Normal file
View file

@ -0,0 +1,20 @@
package utils
import (
"time"
)
type Time struct {
ts time.Time
}
func (t *Time) SetTime(value time.Time) {
t.ts = value
}
func (t Time) GetTime() time.Time {
if !t.ts.IsZero() {
return t.ts
}
return time.Now().In(time.UTC)
}

View file

@ -0,0 +1,24 @@
package utils
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestTime_GetTimeWithDefaultValue(t *testing.T) {
var ts Time
// Assert that time is NOW (+-10 seconds)
assert.InDelta(t, ts.GetTime().Unix(), time.Now().In(time.UTC).Unix(), float64(10))
}
func TestTime_GetTimeWithSetTime(t *testing.T) {
var ts Time
expected := time.Unix(1048722042, 500)
ts.SetTime(expected)
assert.Equal(t, expected, ts.GetTime())
}

View file

@ -1,49 +0,0 @@
package log
import "fmt"
// Colors
// ---------------------------------------------------------
const (
InfoColor = "\033[1;34m%s\033[0m"
NoticeColor = "\033[1;36m%s\033[0m"
WarningColor = "\033[1;33m%s\033[0m"
ErrorColor = "\033[1;31m%s\033[0m"
)
// Define LogFunc prototype
// Function that takes a format string and variadic number
// of arguments (like printf)
// ---------------------------------------------------------
type LogFunc func(format string, args ...interface{})
// Create a log function.
// This is the base logging function. by providing a prefix
// a new log function of LogFunc type will be created
// appending "[ <prefix> ]" before the message.
// ---------------------------------------------------------
func logfn(prefix string) LogFunc {
return func(format string, args ...interface{}) {
format = "[" + prefix + "] " + format + "\n"
fmt.Printf(format, args...)
}
}
// Declare our different log functions.
// ---------------------------------------------------------
var Info LogFunc
var Notice LogFunc
var Warning LogFunc
var Error LogFunc
// Initilize log module
// ---------------------------------------------------------
func init() {
// Initilize functions.
Info = logfn(fmt.Sprintf(InfoColor, "INFO"))
Notice = logfn(fmt.Sprintf(NoticeColor, "NOTICE"))
Warning = logfn(fmt.Sprintf(WarningColor, "WARN"))
Error = logfn(fmt.Sprintf(ErrorColor, "ERROR"))
}

4
scripts/.gitignore vendored
View file

@ -1,2 +1,6 @@
pack/ pack/
info
pkg_info
*.deb *.deb
*.tar
*.tar.*

View file

@ -1,56 +0,0 @@
#!/usr/bin/env bash
BASE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
PACKAGE_BINDIR=${PACKAGE_PREFIX}/bin
PACKAGE_ETCDIR=etc/${PACKAGE_NAME}
PACKAGE_SYSUNITDIR=etc/systemd/system
PACKAGE_SHAREDIR=${PACKAGE_PREFIX}/share/${PACKAGE_NAME}
PACKAGE_DESCRIPTION="HAproxy healthcheck program for EOSIO API."
PACKAGE_TMPDIR="pack"
# Default to 1 if no release is set.
if [[ -z $RELEASE ]]; then
RELEASE="1"
fi
PACKAGE_FULLNAME="${PACKAGE_NAME}_${PACKAGE_VERSION}-${RELEASE}_amd64"
rm -fr ${BASE_DIR}/${PACKAGE_TMPDIR}
# Create debian files.
mkdir -p ${BASE_DIR}/${PACKAGE_TMPDIR}/DEBIAN
echo "Package: ${PACKAGE_NAME}
Version: ${PACKAGE_VERSION}-${RELEASE}
Section: introspection
Priority: optional
Architecture: amd64
Homepage: https://github.com/eosswedenorg/eos-api-healthcheck
Maintainer: Henrik Hautakoski <henrik@eossweden.org>
Description: ${PACKAGE_DESCRIPTION}" &> ${BASE_DIR}/${PACKAGE_TMPDIR}/DEBIAN/control
cat ${BASE_DIR}/${PACKAGE_TMPDIR}/DEBIAN/control
# Create service file
mkdir -p ${BASE_DIR}/${PACKAGE_TMPDIR}/${PACKAGE_SYSUNITDIR}
cat ${BASE_DIR}/template.service \
| sed "s~{{ PACKAGE_NAME }}~${PACKAGE_NAME}~" \
| sed "s~{{ DESCRIPTION }}~${PACKAGE_DESCRIPTION}~" \
| sed "s~{{ PROGRAM }}~/${PACKAGE_PREFIX}/bin/${PACKAGE_NAME}~" \
> ${BASE_DIR}/${PACKAGE_TMPDIR}/${PACKAGE_SYSUNITDIR}/${PACKAGE_NAME}.service
# Cerate config file
mkdir -p ${BASE_DIR}/${PACKAGE_TMPDIR}/${PACKAGE_ETCDIR}
cat ${BASE_DIR}/config \
| sed "s~{{ PACKAGE_NAME }}~${PACKAGE_NAME}~" \
> ${BASE_DIR}/${PACKAGE_TMPDIR}/${PACKAGE_ETCDIR}/env
# Copy program
mkdir -p ${BASE_DIR}/${PACKAGE_TMPDIR}/${PACKAGE_BINDIR}
cp ${BASE_DIR}/../${PACKAGE_PROGRAM} ${BASE_DIR}/${PACKAGE_TMPDIR}/${PACKAGE_BINDIR}/${PACKAGE_NAME}
# Copy files.
mkdir -p ${BASE_DIR}/${PACKAGE_TMPDIR}/${PACKAGE_SHAREDIR}
cp ${BASE_DIR}/../README.md ${BASE_DIR}/${PACKAGE_TMPDIR}/${PACKAGE_SHAREDIR}
fakeroot dpkg-deb --build ${BASE_DIR}/${PACKAGE_TMPDIR} ${BASE_DIR}/${PACKAGE_FULLNAME}.deb

View file

@ -1,7 +0,0 @@
# Default settings for {{ PACKAGE_NAME }}
#
# This is sourced by the systemd unit file.
# Command line flags to pass to {{ PACKAGE_NAME }}
# First is IP to listen to, second is port.
#OPTS="127.0.0.1 1337"

View file

@ -0,0 +1,5 @@
#!/bin/bash
log_install() {
echo -e "[\e[34m::\e[0m] Installing: \e[32m${1}\e[0m"
}

5
scripts/info.sh Normal file
View file

@ -0,0 +1,5 @@
#!/bin/bash
# Info
PROGRAM_NAME=antelope-api-healthcheck
PROGRAM_DESCRIPTION="HAproxy healthcheck program for Antelope Leap API."

61
scripts/install.sh Executable file
View file

@ -0,0 +1,61 @@
#!/bin/bash
############################
# Read cli args #
############################
if [ $# -lt 1 ]; then
echo "$0 <type>"
exit 1
fi
SYSTEM_TYPE=$1
if [ $# -gt 1 ]; then
PREFIX=$2
fi
if [ $# -gt 2 ]; then
DESTDIR=$3
fi
############################
# Exported variables. #
############################
export BASE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
export TEMPLATE_DIR=${BASE_DIR}/templates
export BUILD_DIR=${BASE_DIR}/../build
# Export info variables
set -o allexport
source ${BASE_DIR}/info.sh
set +o allexport
# Directories.
export DESTDIR
export PREFIX
export BINDIR=${PREFIX}/bin
export ETCDIR=/etc/${PROGRAM_NAME}
export LOGDIR=/var/log
export LOGFILE=${LOGDIR}/${PROGRAM_NAME}.log
export SHAREDIR=${PREFIX}/share/${PROGRAM_NAME}
############################
# Run script #
############################
SCRIPT="${BASE_DIR}/install_${SYSTEM_TYPE}.sh"
# Check and call script
if [ ! -x $SCRIPT ]; then
echo "$SCRIPT not found"
exit 1
fi
echo -e "[\e[34m::\e[0m] Installing for system: \e[32m${SYSTEM_TYPE}\e[0m"
if [ -n "$DESTDIR" ]; then
echo -e "[\e[34m::\e[0m] Installing with root: \e[32m${DESTDIR}\e[0m"
fi
bash $SCRIPT

49
scripts/install_freebsd.sh Executable file
View file

@ -0,0 +1,49 @@
#!/bin/bash
# Simple script to install program files on FreeBSD systems
source ${BASE_DIR}/functions/log_install.sh
RCDIR=${DESTDIR}/etc/rc.d
NEWSYSLOGDIR=${DESTDIR}/etc/newsyslog.conf.d
# Common variables
PID_FILE=/var/run/${PROGRAM_NAME}.pid
# rc does not like "-" in the filename.
RC_NAME=$(echo ${PROGRAM_NAME} | sed "s~-~_~g")
############################
# Create rc file #
############################
log_install ${RCDIR}/${RC_NAME}
mkdir -p ${RCDIR}
cat ${TEMPLATE_DIR}/rc.conf \
| sed "s~{{ RC_NAME }}~${RC_NAME}~g" \
| sed "s~{{ PID_FILE }}~${PID_FILE}~g" \
| sed "s~{{ LOG_FILE }}~${LOGFILE}~" \
| sed "s~{{ PROGRAM_DESCRIPTION }}~${PROGRAM_DESCRIPTION}~" \
| sed "s~{{ PROGRAM }}~${BINDIR}/${PROGRAM_NAME}~" \
> ${RCDIR}/${RC_NAME}
# Must be executable.
chmod 755 ${RCDIR}/${RC_NAME}
############################
# Create newsyslog config #
############################
log_install ${NEWSYSLOGDIR}/${PROGRAM_NAME}.conf
mkdir -p ${NEWSYSLOGDIR}
cat ${TEMPLATE_DIR}/newsyslog.conf \
| sed "s~{{ LOG_FILE }}~${LOGFILE}~" \
| sed "s~{{ PID_FILE }}~${PID_FILE}~g" \
> ${NEWSYSLOGDIR}/${PROGRAM_NAME}.conf
############################
# Copy binary #
############################
log_install ${DESTDIR}${BINDIR}/${PROGRAM_NAME}
mkdir -p ${DESTDIR}/${BINDIR}
cp ${BUILD_DIR}/${PROGRAM_NAME} ${DESTDIR}${BINDIR}/${PROGRAM_NAME}

64
scripts/install_linux.sh Executable file
View file

@ -0,0 +1,64 @@
#!/bin/bash
# Script to install program files on linux systems
source ${BASE_DIR}/functions/log_install.sh
SYSTEMDDIR=${DESTDIR}/lib/systemd/system
SYSTEMDLINKDIR=${DESTDIR}/etc/systemd/system
RSYSLOGDIR=${DESTDIR}/etc/rsyslog.d
SYSLOG_NG_DIR=${DESTDIR}/etc/syslog-ng/conf.d
LOGROTATEDIR=${DESTDIR}/etc/logrotate.d
# Create service file
log_install ${SYSTEMDDIR}/${PROGRAM_NAME}.service
mkdir -p ${SYSTEMDDIR}
cat ${TEMPLATE_DIR}/sysunit.service \
| sed "s~{{ PROGRAM_NAME }}~${PROGRAM_NAME}~" \
| sed "s~{{ PROGRAM_DESCRIPTION }}~${PROGRAM_DESCRIPTION}~" \
| sed "s~{{ PROGRAM }}~${BINDIR}/${PROGRAM_NAME}~" \
> ${SYSTEMDDIR}/${PROGRAM_NAME}.service
# Create systemd symlink
log_install ${SYSTEMDLINKDIR}/${PROGRAM_NAME}.service
mkdir -p ${SYSTEMDLINKDIR}
ln -s -T /lib/systemd/system/${PROGRAM_NAME}.service ${SYSTEMDLINKDIR}/${PROGRAM_NAME}.service
# Create systemd/init.d config file
log_install ${DESTDIR}/etc/sysconfig/${PROGRAM_NAME}
mkdir -p ${DESTDIR}/etc/sysconfig
cat ${TEMPLATE_DIR}/config \
| sed "s~{{ PROGRAM_NAME }}~${PROGRAM_NAME}~" \
> ${DESTDIR}/etc/sysconfig/${PROGRAM_NAME}
# Create rsyslog file
log_install ${RSYSLOGDIR}/49-${PROGRAM_NAME}.conf
mkdir -p ${RSYSLOGDIR}
cat ${TEMPLATE_DIR}/rsyslog.conf \
| sed "s~{{ PROGRAM }}~${PROGRAM_NAME}~" \
| sed "s~{{ LOG_FILE }}~${LOGFILE}~" \
> ${RSYSLOGDIR}/49-${PROGRAM_NAME}.conf
# Create syslog-ng file
log_install ${SYSLOG_NG_DIR}/${PROGRAM_NAME}.conf
mkdir -p ${SYSLOG_NG_DIR}
cat ${TEMPLATE_DIR}/syslog-ng.conf \
| sed "s~{{ PROGRAM }}~${PROGRAM_NAME}~" \
| sed "s~{{ LOG_FILE }}~${LOGFILE}~" \
> ${SYSLOG_NG_DIR}/${PROGRAM_NAME}.conf
# Create logrotate file
log_install ${LOGROTATEDIR}/${PROGRAM_NAME}.conf
mkdir -p ${LOGROTATEDIR}
cat ${TEMPLATE_DIR}/logrotate.conf \
| sed "s~{{ LOG_FILE }}~${LOGFILE}~" \
> ${LOGROTATEDIR}/${PROGRAM_NAME}.conf
chmod 644 ${LOGROTATEDIR}/${PROGRAM_NAME}.conf
# Copy program
log_install ${DESTDIR}${SHAREDIR}
mkdir -p ${DESTDIR}/${BINDIR}
cp ${BUILD_DIR}/${PROGRAM_NAME} ${DESTDIR}${BINDIR}/${PROGRAM_NAME}
# Copy files.
mkdir -p ${DESTDIR}${SHAREDIR}
cp ${BASE_DIR}/../README.md ${DESTDIR}${SHAREDIR}

38
scripts/package.sh Executable file
View file

@ -0,0 +1,38 @@
#!/bin/bash
############################
# Read cli args #
############################
if [ $# -lt 1 ]; then
echo "$0 <type>"
exit 1
fi
PKG_TYPE=$1
# Setup vars
export BASE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
# export
export PKGROOT
export BUILDDIR
############################
# Run script #
############################
SCRIPT="${BASE_DIR}/package_${PKG_TYPE}.sh"
# Check and call script
if [ ! -x $SCRIPT ]; then
echo "$SCRIPT not found"
exit 1
fi
# Export info variables
set -o allexport
source ${BASE_DIR}/info.sh
set +o allexport
bash $SCRIPT

7
scripts/package_freebsd.sh Executable file
View file

@ -0,0 +1,7 @@
#!/bin/bash
PROGRAM_ARCH=$(go env GOARCH)
TAR_FILENAME="${PROGRAM_NAME}-${PROGRAM_VERSION}-freebsd-${PROGRAM_ARCH}.tar.gz"
echo "Create archive: ${BUILDDIR}/${TAR_FILENAME}"
tar -C ${PKGROOT} --owner root --group root -zcvf ${BUILDDIR}/${TAR_FILENAME} .

View file

@ -1,21 +0,0 @@
[Unit]
Description={{ DESCRIPTION }}
After=network.target
[Service]
EnvironmentFile=-/etc/{{ PACKAGE_NAME }}/env
Type=simple
# Another Type: forking
#User=nanodano
#WorkingDirectory=/home/nanodano
ExecStart={{ PROGRAM }} $OPTS
Restart=on-failure
# Other restart options: always, on-abort, etc
# The install section is needed to use
# `systemctl enable` to start on boot
# For a user service that you want to enable
# and start automatically, use `default.target`
# For system level services, use `multi-user.target`
[Install]
WantedBy=multi-user.target

7
scripts/templates/config Normal file
View file

@ -0,0 +1,7 @@
# Default settings for {{ PROGRAM_NAME }}
#
# This is sourced by the systemd unit file or init.d
# Command line flags to pass to {{ PROGRAM_NAME }}
# Positional agruments are IP to listen to, then port number.
ANTELOPE_API_HEALTCHECK_OPTS="--log-format=logfmt 127.0.0.1 1337"

View file

@ -0,0 +1,9 @@
{{ LOG_FILE }} {
daily
dateext
dateformat _%Y-%m-%d
rotate 10
compress
notifempty
copytruncate
}

View file

@ -0,0 +1,2 @@
# logfilename [owner:group] mode count size when flags [/pid_file] [sig_num]
{{ LOG_FILE }} 640 3 * @T10 JC {{ PID_FILE }}

32
scripts/templates/rc.conf Normal file
View file

@ -0,0 +1,32 @@
#!/bin/sh
#
# Add the following lines to /etc/rc.conf to configure antelope_api_healthcheck:
#
# antelope_api_healthcheck_args : arguments to the command.
#
# antelope_api_healthcheck_logfile : file to log to (default /var/log/${name}.log)
#
# PROVIDE: {{ RC_NAME }}
# REQUIRE: netif FILESYSTEMS
. /etc/rc.subr
name="{{ RC_NAME }}"
desc="{{ PROGRAM_DESCRIPTION }}"
logfile="${antelope_api_healthcheck_logfile:-{{ LOG_FILE }}}"
pidfile="{{ PID_FILE }}"
command="{{ PROGRAM }}"
command_args="-p ${pidfile} -l ${logfile} ${antelope_api_healthcheck_args}"
start_cmd="${name}_start"
antelope_api_healthcheck_start()
{
echo "Starting ${name}"
${command} ${command_args} 2>&1 &
}
load_rc_config $name
run_rc_command "$1"

View file

@ -0,0 +1,5 @@
if $programname == '{{ PROGRAM }}' then {
{{ LOG_FILE }}
stop
}

View file

@ -0,0 +1,3 @@
filter f_api-healthcheck { program("{{ PROGRAM }}"); };
destination d_api-healthcheck { file("{{ LOG_FILE }}"); };
log { source(s_src); filter(f_api-healthcheck); destination(d_api-healthcheck); };

View file

@ -0,0 +1,12 @@
[Unit]
Description={{ PROGRAM_DESCRIPTION }}
After=network.target
[Service]
EnvironmentFile=-/etc/sysconfig/{{ PROGRAM_NAME }}
Type=simple
ExecStart={{ PROGRAM }} $ANTELOPE_API_HEALTCHECK_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target

173
server.go
View file

@ -1,173 +0,0 @@
package main
import (
"os"
"fmt"
"time"
"strings"
"strconv"
"./log"
"./haproxy"
"./eosapi"
"github.com/firstrow/tcp_server"
)
// check_api - Validates head block time.
// ---------------------------------------------------------
func check_api(host string, port int, block_time float64) (haproxy.HealthCheckStatus, string) {
info, err := eosapi.GetInfo(host, port)
if err != nil {
msg := fmt.Sprintf("%s", err);
return haproxy.HealthCheckFailed, msg
}
// Validate head block.
now := time.Now().In(time.UTC)
diff := now.Sub(info.HeadBlockTime).Seconds()
if diff > block_time {
return haproxy.HealthCheckDown,
fmt.Sprintf("Taking offline because head block is lagging %.0f seconds", diff)
} else if diff < -block_time {
return haproxy.HealthCheckDown,
fmt.Sprintf("Taking offline because head block is %.0f seconds into the future", diff)
}
return haproxy.HealthCheckUp, "OK"
}
// check_api_v2 (hyperion)
// Validates block num diff between
// nodeos and elasticsearch
// ---------------------------------------------------------
func check_api_v2(host string, port int, offset int64) (haproxy.HealthCheckStatus, string) {
health, err := eosapi.GetHealth(host, port)
if err != nil {
msg := fmt.Sprintf("%s", err);
return haproxy.HealthCheckFailed, msg
}
// Fetch elasticsearch and nodeos block numbers from json.
var es_block int64 = 0
var node_block int64 = 0
for _, v := range health.Health {
if v.Name == "Elasticsearch" {
es_block = (int64) (v.Data["last_indexed_block"].(float64))
} else if v.Name == "NodeosRPC" {
node_block = (int64) (v.Data["head_block_num"].(float64))
}
}
// Error out if ether or both are zero.
if es_block == 0 || node_block == 0 {
msg := fmt.Sprintf("Failed to get Elasticsearch and/or nodeos " +
"block numbers (es: %d, eos: %d)", es_block, node_block)
return haproxy.HealthCheckFailed, msg
}
// Check if ES is behind or in the future.
diff := node_block - es_block;
if diff > offset {
return haproxy.HealthCheckDown,
fmt.Sprintf("Taking offline because Elastic is %d blocks behind", diff)
} else if diff < -offset {
return haproxy.HealthCheckDown,
fmt.Sprintf("Taking offline because Elastic is %d blocks into the future", -1 * diff)
}
return haproxy.HealthCheckUp, "OK"
}
// argv_listen_addr
// Parse listen address from command line.
// ---------------------------------------------------------
func argv_listen_addr() string {
var addr string
argv := os.Args[1:]
if len(argv) > 0 {
addr = argv[0]
} else {
addr = "127.0.0.1"
}
addr += ":"
if len(argv) > 1 {
addr += argv[1]
} else {
addr += "1337"
}
return addr
}
// main
// ---------------------------------------------------------
func main() {
server := tcp_server.New(argv_listen_addr())
// TCP Client connect.
server.OnNewClient(func(c *tcp_server.Client) {
//fmt.Println("# Client connected")
});
// TCP Client sends message.
server.OnNewMessage(func(c *tcp_server.Client, message string) {
var host string
var port int = 80
var block_time int = 10
var version string = "v1"
// Parse host + port.
split := strings.Split(strings.TrimSpace(message), ":")
host = split[0]
if len(split) > 1 {
p, err := strconv.ParseInt(split[1], 10, 32)
if err == nil {
port = int(p)
}
}
if len(split) > 2 {
p, err := strconv.ParseInt(split[2], 10, 32)
if err == nil {
block_time = int(p)
}
}
if len(split) > 3 {
version = split[3]
}
// Check api.
var status haproxy.HealthCheckStatus
var msg string
if version == "v2" {
status, msg = check_api_v2(host, port, int64(block_time / 2))
} else {
version = "v1"
status, msg = check_api(host, port, float64(block_time))
}
log.Info("Status %s - %s:%d (%d blocks): %s",
version, host, port, block_time / 2, status)
if status != haproxy.HealthCheckUp && len(msg) > 0 {
log.Warning(msg)
}
// Report status to HAproxy
c.Send(fmt.Sprintln(status))
c.Close()
});
// TCP Client disconnect.
server.OnClientConnectionClosed(func(c *tcp_server.Client, err error) {
//fmt.Println("# Client disconnected")
});
server.Listen()
}

68
set-version.sh Executable file
View file

@ -0,0 +1,68 @@
#!/bin/bash
# Simple script to make it easy to update the version number for the program.
#
# Debian
# ----------------------------
# For releasing debian packages, there must be a name and email associated with the version.
# You can pass "-n|--name" and "-e|--email" as parameters to this script.
#
# You can if you want set the following enviroment variables in your shell to have your name and email be inserted without cli flags.
# DEB_MAINT_NAME
# DEB_MAINT_EMAIL
function usage() {
echo "Usage: ${0##*/} [ -h|--help ] [ -n|--name <value> ] [ -e|--email <value> ] [ --nodebchanges ] <version>"
exit 1
}
eval set -- "$(getopt -n "${0##*/}" -o "hn:e:" -l "help,name:,email:,nodebchanges" -- "$@")"
WRITE_DEBCHANGES=1
while true; do
case $1 in
-n|--name)
shift
DEB_MAINT_NAME=$1
;;
-e|--email)
shift
DEB_MAINT_EMAIL=$1
;;
--nodebchanges)
WRITE_DEBCHANGES=0
;;
-h|--help) usage ;;
--) shift
break
;;
esac
shift
done
[ $# -gt 0 ] || [ $? -eq 0 ] || usage
VERSION=$@
if [ ${WRITE_DEBCHANGES} -ne 0 ]; then
# Update debian changelog
ex debian/changelog <<EOF
1 insert
antelope-api-healthcheck (${VERSION}) unstable; urgency=medium
*
-- ${DEB_MAINT_NAME} <${DEB_MAINT_EMAIL}> $(date -R)
.
xit
EOF
echo -e "[\e[34m::\e[0m] Inserted template in \e[1mdebian/changelog\e[0m. \e[33mMake sure you edit this file with the actual changes!\e[0m"
else :
echo -e "[\e[33m::\e[0m] Skipping \e[1mdebian/changelog\e[0m."
fi
# Update Makefile
sed -i "s:PROGRAM_VERSION\(\s*\)=\(\s*\)\(.*\):PROGRAM_VERSION\1=\2$VERSION:g" Makefile
echo -e "[\e[34m::\e[0m] Set PROGRAM_VERSION=\e[34m$VERSION\e[0m in \e[1mMakefile\e[0m"