Giter VIP home page Giter VIP logo

wait4x's Introduction

Wait4X

GitHub Workflow Status (branch) Coverage Status Go Report Card Docker Pulls GitHub all releases Go Reference

Wait4X allows you to wait for a port or a service to enter the requested state, with a customizable timeout and interval time.

Table of Contents

Features

  • Supports various protocols:
    • TCP
    • HTTP
  • Supports various services:
    • Redis
    • MySQL
    • PostgreSQL
    • InfluxDB
    • MongoDB
    • RabbitMQ
    • Temporal
  • Reverse Checking: Invert the sense of checking to find a free port or non-ready services
  • Parallel Checking: You can define multiple inputs to be checked
  • Exponential Backoff Checking: Retry using an exponential backoff approach to improve efficiency and reduce errors.
  • CI/CD Friendly: Well-suited to be part of a CI/CD pipeline step
  • Cross Platform: One single pre-built binary for Linux, Mac OSX, and Windows
  • Importable: Beside the CLI tool, Wait4X can be imported as a pkg in your Go app
  • Command execution: Execute your desired command after a successful wait

Installation

There are many ways to install Wait4X

with Docker

Wait4X provides automatically updated Docker images within Docker Hub. It is possible to always use the latest stable tag.

Pull the image from the docker index.

docker pull atkrad/wait4x:latest

then you can launch the wait4x container.

docker run --rm --name='wait4x' \
    atkrad/wait4x:latest --help

From binary

Choose the file matching the destination platform from the release page, copy the URL and replace the URL within the commands below:

Linux

curl -#LO https://github.com/atkrad/wait4x/releases/latest/download/wait4x-linux-amd64.tar.gz
tar --one-top-level -xvf wait4x-linux-amd64.tar.gz
cp ./wait4x-linux-amd64/wait4x /usr/local/bin/wait4x

Mac OSX

curl -#LO https://github.com/atkrad/wait4x/releases/latest/download/wait4x-darwin-amd64.tar.gz
tar --one-top-level -xvf wait4x-darwin-amd64.tar.gz
cp ./wait4x-darwin-amd64/wait4x /usr/local/bin/wait4x

Windows

curl -#LO https://github.com/atkrad/wait4x/releases/latest/download/wait4x-windows-amd64.tar.gz
tar --one-top-level -xvf wait4x-windows-amd64.tar.gz

Verify SHA256 Checksum

Wait4X generates checksum for all binaries with sha256sum to prevent against unwanted modification of binaries. To validate the archive files, download the checksum file which ends in .sha256sum for the archive file that you downloaded and use the sha256sum command line tool.

curl -#LO https://github.com/atkrad/wait4x/releases/latest/download/wait4x-linux-amd64.tar.gz.sha256sum
sha256sum --check wait4x-linux-amd64.tar.gz.sha256sum

From package

You can find the Wait4X package in some Linux distributions.

Packaging status

On Alpine Linux

You can install the wait4x package from the official sources:

apk add wait4x

On Arch Linux (AUR)

You can install the wait4x package from the Arch User Repository:

yay -S wait4x

Examples

TCP

# If you want checking just tcp connection
wait4x tcp 127.0.0.1:9090

HTTP

# If you want checking just http connection
wait4x http https://ifconfig.co

# If you want checking http connection and expect specify http status code
wait4x http https://ifconfig.co --expect-status-code 200

# If you want checking http connection, status code and match the response body.
# Note: You can write any regex that compatible with Golang syntax (https://pkg.go.dev/regexp/syntax#hdr-Syntax)
wait4x http https://ifconfig.co/json --expect-status-code 200 --expect-body='"country":\s"Netherlands"'

# If you want to check a http response header
# NOTE: the value in the expected header is regex.
# Sample response header: Authorization Token 1234ABCD
# You can match it by these ways:

# Full key value:
wait4x http https://ifconfig.co --expect-header "Authorization=Token 1234ABCD"

# Value starts with:
wait4x http https://ifconfig.co --expect-header "Authorization=Token"

# Regex value:
wait4x http https://ifconfig.co --expect-header "Authorization=Token\s.+"

# Body JSON value:
# Note: the value in the expected JSON will be processed by gjson.
# Note: the complete response MUST be in JSON format to be processed. If one part of the response is JSON
# and the rest is something else like HTML, please use --expect-body instead.
# To know more about JSON syntax https://github.com/tidwall/gjson/blob/master/SYNTAX.md
wait4x http https://ifconfig.co/json --expect-body-json "user_agent.product"

# Body XPath
wait4x http https://www.kernel.org/ --expect-body-xpath "//*[@id="tux-gear"]"

# Request headers:
wait4x http https://ifconfig.co --request-header "Content-Type: application/json" --request-header "Authorization: Token 123"

# Enable exponential backoff retry
wait4x http https://ifconfig.co --expect-status-code 200 --backoff-policy exponential  --backoff-exponential-max-interval 120s --timeout 120s

Redis

# Checking Redis connection
wait4x redis redis://127.0.0.1:6379

# Specify username, password and db
wait4x redis redis://user:password@localhost:6379/1

# Checking Redis connection over unix socket
wait4x redis unix://user:password@/path/to/redis.sock?db=1

# Checking a key existence
wait4x redis redis://127.0.0.1:6379 --expect-key FOO

# Checking a key existence and matching the value
# Note: You can write any regex that compatible with Golang syntax (https://pkg.go.dev/regexp/syntax#hdr-Syntax)
wait4x redis redis://127.0.0.1:6379 --expect-key "FOO=^b[A-Z]r$"

MySQL

# Checking MySQL TCP connection
wait4x mysql user:password@tcp(localhost:5555)/dbname

# Checking MySQL UNIX Socket connection
wait4x mysql username:password@unix(/tmp/mysql.sock)/myDatabase

Syntax for the database connection string: https://github.com/go-sql-driver/mysql#dsn-data-source-name

PostgreSQL

# Checking PostgreSQL TCP connection
wait4x postgresql 'postgres://bob:[email protected]:5432/mydb?sslmode=disable'

# Checking PostgreSQL Unix socket connection
wait4x postgresql 'postgres://bob:secret@/mydb?host=/var/run/postgresql'

Syntax for the database URL: https://pkg.go.dev/github.com/lib/pq

InfluxDB

# Checking InfluxDB connection
wait4x influxdb http://localhost:8086

MongoDB

# Checking MongoDB connection
wait4x mongodb 'mongodb://127.0.0.1:27017'

# Checking MongoDB connection with credentials and options
wait4x mongodb 'mongodb://user:[email protected]:27017/?maxPoolSize=20&w=majority'

RabbitMQ

# Checking RabbitMQ connection
wait4x rabbitmq 'amqp://127.0.0.1:5672'

# Checking RabbitMQ connection with credentials and vhost
wait4x rabbitmq 'amqp://guest:[email protected]:5672/vhost'

Temporal

# Checking just Temporal server health check
wait4x temporal server 127.0.0.1:7233

# Checking insecure Temporal server (no TLS)
wait4x temporal server 127.0.0.1:7233 --insecure-transport

# Checking a task queue that has registered workers (pollers) or not
wait4x temporal worker 127.0.0.1:7233 --namespace __YOUR_NAMESPACE__ --task-queue __YOUR_TASK_QUEUE__

# Checking the specific a Temporal worker (pollers)
wait4x temporal worker 127.0.0.1:7233 --namespace __YOUR_NAMESPACE__ --task-queue __YOUR_TASK_QUEUE__ --expect-worker-identity-regex ".*@__HOSTNAME__@.*"

Command Execution

We need to wait for something in order to execute something else. This feature is also supported by using -- after a feature parameter.

Let's have some scenarios:

  • As soon as the MySQL server becomes ready, run a Django migration:
wait4x mysql username:password@unix(/tmp/mysql.sock)/myDatabase -- django migrate
  • As soon as the new version of the website becomes ready, send an email to the support team:
wait4x http https://www.kernel.org/ --expect-body-xpath "//*[@id="website-logo"]" -- mail -s "The new version of the website has just been released" support@company < /dev/null
  • Chain type: when PostgreSQL becomes ready, then wait for RabbitMQ, when it becomes ready, then run the integration tests:
wait4x postgresql 'postgres://bob:secret@/mydb?host=/var/run/postgresql' -t 1m -- wait4x rabbitmq 'amqp://guest:[email protected]:5672/vhost' -t 30s -- ./integration-tests.sh
  • Using an environment variable in the command:
EMAIL="support@company" wait4x http https://www.kernel.org/ --expect-body-xpath "//*[@id="website-logo"]" -- mail -s "New version of the website has just released" $EMAIL < /dev/null

# Or

export EMAIL="support@company"
wait4x http https://www.kernel.org/ --expect-body-xpath "//*[@id="website-logo"]" -- mail -s "New version of the website has just released" $EMAIL < /dev/null

wait4x's People

Contributors

alizdavoodi avatar atkrad avatar dependabot[bot] avatar honwen avatar mortymacs avatar mossroy avatar sbaeurle avatar ykis-0-0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

wait4x's Issues

Disable logging

Is it possible to disable logging?

Would be nice to have a --quiet or --slient flag.

Kafka support

It would be great if wait4x was able to test a connection to a Kafka cluster (based on a given bootstrap servers string)

A workaround is to test with tcp, but it's far less precise: the kafka cluster can be up and running even if one of the bootstrap servers is down (for example)

--expect-body-json comparison with value

Hi, i am using wait4x in the pipeline using the HTTP provider in order to compare a specific body JSON key with a specific value. AFAIK, also looking at the gjson doc, this seems not possible.
For example a body with

{"version": 1234} 

cannot be done afaik with --expect-body-json with something like:

wait4x http https://ifconfig.co/json --expect-body-json "version==1234" or something similar.

Alpine Linux version don't support Command Execution

➜  dockerProjects docker exec -it 265f808d5b08 sh
/ # apk add wait4x
fetch https://dl-cdn.alpinelinux.org/alpine/v3.16/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.16/community/x86_64/APKINDEX.tar.gz
(1/1) Installing wait4x (0.4.0-r7)
Executing busybox-1.35.0-r15.trigger
OK: 33 MiB in 43 packages
/ # wait4x version
Version:           v0.4.0
Go version:        go1.18.4
Git commit:        9fcfdc13
Built:             2020-12-21T19:05:13Z
OS/Arch:           linux/amd64
/ # wait4x http http://www.baidu.com http://www.qq.com -- echo "The api is up! Let's use it"
INFO[0000] Checking HTTP connection ...
/ # wait4x http http://www.baidu.com http://www.qq.com -- echo "The api is up! Let's use it"
INFO[0000] Checking HTTP connection ...
/ # wait4x http http://www.baidu.com http://www.qq.com -- echo "The api is up! Let's use it"
INFO[0000] Checking HTTP connection ...
/ # wait4x http http://www.baidu.com http://www.qq.com -- echo "The api is up! Let's use it"
INFO[0000] Checking HTTP connection ...
/ # exit
➜  dockerProjects

Wait indefinitely

The --timeout command-line parameter allows to set a timeout (10s by default).
But I have some cases where I'd like to wait for ever.

Maybe a value of zero could be considered as "for ever"? (It's not the case currently).
Or any other suitable command-line parameter to do that?

HEAD http method support

Hello!

What do you think about supporting head method for http-requests? Now the only GET and POST methods are supported. Sometimes the only thing you want to know is upstream response status code. Upstream page may be hard to GET. With HEAD it will be simpler. Another case is when you only do --expect-header-check is it enough to send HEAD-request.

For example:

# implicit GET http-request:
wait4x http https://ifconfig.co --expect-header "Authorization=Token 1234ABCD"

# explicit HEAD http-request:
wait4x http https://ifconfig.co --expect-header "Authorization=Token 1234ABCD" --http-method head

# explicit HEAD http-request:
wait4x http https://ifconfig.co --expect-status-code 200 --http-method head

All commands work the same, but explicit --http-method head argument sends head-request in some cases.

Please provide arm images, too

I really like this tool, and use it in Kubernetes initContainers.

But the docker hub images (and release binaries) are only for amd64 architecture.
Would it be possible to provide images for arm architecture, too?

It would allow to use them on RaspberryPi-like devices, and also on Apple M1/M2 CPUs

Support Context in Checkers

It would great if we can use context instead of pure timeout in checkers but it also needs support from raw connectors.

Adjust pipeline to output .exe for Windows instead of file without extension

If one wants to use Wait4X on Windows or with Windows Containers the current output of the github pipeline cannot be used directly and must be renamed to wait4x.exe to become available in both Powershell and CMD.
Is it possible to change the pipeline output to reflect this requirement already?

PS. If needed I can adjust the stuff myself, just wanted to start a discussion about it first.

Support POSTing data in http

It would be nice to be able to specify the http request as a POST request with some body.

Something like --with-body '{"foo":"bar"}' could change the verb to POST and behave like the curl -d flag.

Multiple Address Support Request

What do you think about adding multiple addresses support? For example for HTTP it can be something like this:

wait4x http http://srv1:8080,http://srv2:8080

If both http://srv1:8080 and http://srv2:8080 return the expected result, wait4x exits successfully and otherwise it should be failed.

Maybe we can use comma separated string that is mentioned above or split strings like this:

wait4x http http://srv1:8080  http://srv1:8080

It can help us a lot to improve our deployment process.

Incorrect log level for errors when checking resources

The application does not log errors (e.g. incorrect sql password or unreachable host) correctly.

With -l debug the errors are readable, however they should be logged using the error level imo.

Example:

2022-11-14T15:15:39+01:00 INF [PostgreSQL] Checking the [...]:5432 ...
2022-11-14T15:15:39+01:00 DBG pq: Passwort-Authentifizierung für Benutzer postgres fehlgeschlagen
2022-11-14T15:15:40+01:00 INF [PostgreSQL] Checking the [...]:5432 ...
2022-11-14T15:15:40+01:00 DBG pq: Passwort-Authentifizierung für Benutzer postgres fehlgeschlagen
2022-11-14T15:15:41+01:00 INF [PostgreSQL] Checking the [...]:5432 ...
2022-11-14T15:15:41+01:00 DBG pq: Passwort-Authentifizierung für Benutzer postgres fehlgeschlagen

Do not reveal passwords in logs

It's the case at least with MySQL and PostgreSQL

When wait4x fails to connect (for example because the DNS name does not yet exist under k8s), it outputs something like:

2023-05-05T23:17:16+02:00 ERR Expectation failed error="failed to establish a connection to the mysql server, caused by: dial tcp: lookup mymariadb on 10.43.0.10:53: no such host" dsn=username:password@tcp(mymariadb:3306)/mydatabase

or

2023-05-06T09:57:46+02:00 ERR Expectation failed error="failed to establish a connection to the postgresql server, caused by: dial tcp 10.43.75.241:5432: connect: connection refused" dsn=postgres://username:password@mypostgres:5432/mydatabase?sslmode=disable

which reveals the password

Ideally, the password would be replaced by stars, or any other means.

NATS Support

well if its getting Kafka support then can we have the NATS too :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.