Code Monkey home page Code Monkey logo

yosoy's Introduction

yosoy Go Docker

yosoy is an HTTP service for stubbing and prototyping distributed applications. It is a service that introduces itself to the caller and prints useful information about its runtime environment.

yosoy is extremely useful when creating a stub for a distributed application, as it provides more meaningful responses than, for example, a default nginx welcome page. Further, yosoy incorporates a built-in reachability analyzer to facilitate troubleshooting connectivity issues in distributed systems. A dedicated reachability analyzer endpoint validates network connectivity between yosoy and remote endpoints.

Typical use cases include:

  • Testing HTTP routing and ingress
  • Testing HTTP load balancing
  • Testing HTTP caching
  • Executing reachability analysis
  • Stubbing and prototyping distributed applications

"Yo soy" means "I am" in Spanish.

API

yosoy responds to all requests with a JSON containing the information about:

  • HTTP request:
    • Host
    • Request URI
    • Method
    • Scheme
    • Proto
    • URL
    • Remote IP
    • HTTP headers
    • HTTP proxy headers
  • host:
    • Hostname
    • How many times it was called
    • Env variables if YOSOY_SHOW_ENVS is set to true, yes, on, or 1
    • Files' contents if YOSOY_SHOW_FILES is set to a comma-separated list of (valid) files

Check Sample JSON response to see how you can use yosoy for stubbing/prototyping/troubleshooting distributed applications.

ping/reachability analyzer

yosoy includes a simple ping/reachability analyzer. You can use this functionality when prototyping distributed systems to validate whether a given component can reach a specific endpoint. yosoy exposes a dedicated /_/yosoy/ping endpoint which accepts the following 4 query parameters:

  • h - required - hostname of the endpoint
  • p - required - port of the endpoint
  • n - optional - network, all valid Go networks are supported (including the most popular ones like tcp, udp, IPv4, IPV6, etc.). If n parameter is not provided, it defaults to tcp. If n parameter is set to unknown network, an error will be returned.
  • t - optional - timeout in seconds. If t parameter is not provided, it defaults to 10. If t contains invalid integer literal, an error will be returned.

Check Sample ping/reachability analyzer responses to see how you can use yosoy for troubleshooting network connectivity.

Docker image

The docker image is available on docker hub and ghcr.io:

docker pull lukasz/yosoy
docker pull ghcr.io/lukaszbudnik/yosoy

It exposes HTTP service on port 80.

Kubernetes example

There is a sample Kubernetes deployment file in the test folder. It uses both YOSOY_SHOW_ENVS and YOSOY_SHOW_FILES features. The deployment uses Kubernetes Downward API to expose labels and annotations as volume files which are then returned by yosoy.

Deploy it to minikube and execute curl to the service a couple of times:

# start minikube
minikube start
# deploy test service
kubectl apply -f test/deployment.yaml
# tunnel to it and copy the URL as $URL variable
minikube service --url camarero
# simulate some HTTP requests
curl -H "Host: gateway.myapp.com" $URL/camarero/abc
curl -H "Host: gateway.myapp.com" $URL/camarero/abc
curl -H "Host: gateway.myapp.com" $URL/camarero/abc
curl -H "Host: gateway.myapp.com" $URL/camarero/abc

Sample JSON response

A sample yosoy JSON response to a request made from a single page application (SPA) to a backend API deployed in Kubernetes behind nginx ingress and haproxy-auth-gateway looks like this:

{
  "host": "api.localtest.me",
  "proto": "HTTP/1.1",
  "method": "GET",
  "scheme": "https",
  "requestUri": "/camarero",
  "url": "https:///camarero",
  "remoteAddr": "192.168.65.3",
  "counter": 1,
  "headers": {
    "Accept": ["*/*"],
    "Accept-Encoding": ["gzip, deflate, br"],
    "Accept-Language": ["en-US,en;q=0.9,pl-PL;q=0.8,pl;q=0.7,es;q=0.6"],
    "Authorization": [
      "Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJXejFuaDNCWDI4UHMxVEMzSDRoOW52Q1VWRXpjVVBzQms4Z1NmeEp4ZS1JIn0.eyJleHAiOjE2Mjk4MjM3OTMsImlhdCI6MTYyOTgyMjg5MywiYXV0aF90aW1lIjoxNjI5ODIyODkyLCJqdGkiOiI3ZmQzMjkwZi05NjMyLTQ0NzEtYjRjOS1lNTFjZDYwMjllYjgiLCJpc3MiOiJodHRwczovL2F1dGgubG9jYWx0ZXN0Lm1lL2F1dGgvcmVhbG1zL2hvdGVsIiwic3ViIjoiMDdmYzM3YmYtMmJjNy00ZTRmLWE3MDUtYzRjNjgzNTIwYmU1IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoicmVhY3QiLCJub25jZSI6IjQzNDhmMjU5LTliYTYtNDk2ZC04N2I5LWZmZGYzNDMwN2UzOSIsInNlc3Npb25fc3RhdGUiOiJmNTM5OGI3Ny01OTNhLTQ3OWYtOTc5NS00NGIyNGJjMjhkYjQiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbImh0dHBzOi8vbHVrYXN6YnVkbmlrLmdpdGh1Yi5pbyJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiY2FtYXJlcm8iXX0sInNjb3BlIjoib3BlbmlkIGVtYWlsIHByb2ZpbGUiLCJzaWQiOiJmNTM5OGI3Ny01OTNhLTQ3OWYtOTc5NS00NGIyNGJjMjhkYjQiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJKdWxpbyIsInByZWZlcnJlZF91c2VybmFtZSI6Imp1bGlvIiwiZ2l2ZW5fbmFtZSI6Ikp1bGlvIn0.t5y3L4FzGxM0zwI3fskDI8Kemxz_izcvPPKciSEvNHnZWGQK-9AclGNFz_A9cLFSkpc6l6lBmt7WaC0i04c4h1a9G9AOFImmVXPMPDdTXOQ4aah4CvlN6Fy8ShvSHrQA-wMHEELBpIFsKFx2WP3QHiy27ycr3kqQzW4QymyU7J8tM4-qKR_H1_8aiNOrm5fIED-nEP096V2zvWXiGZX7ts6XE2-annhKphCABLdmIiwgDUnhlAz0hdiDrDbIjzr0ldW4AnUkSQxIZY0PnoEnGVuUvkOYvJpFx10gjORMnRgHSEj9Mk5dtyVGHcihZ5TntCL40WoymNxae6K4-FH3Lw"
    ],
    "Origin": ["https://lukaszbudnik.github.io"],
    "Referer": ["https://lukaszbudnik.github.io/"],
    "Sec-Ch-Ua": [
      "\" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\""
    ],
    "Sec-Ch-Ua-Mobile": ["?0"],
    "Sec-Fetch-Dest": ["empty"],
    "Sec-Fetch-Mode": ["cors"],
    "Sec-Fetch-Site": ["cross-site"],
    "User-Agent": [
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"
    ],
    "X-Forwarded-For": ["192.168.65.3", "10.1.3.9"],
    "X-Forwarded-Host": ["api.localtest.me"],
    "X-Forwarded-Port": ["443"],
    "X-Forwarded-Proto": ["https"],
    "X-Real-Ip": ["192.168.65.3"],
    "X-Request-Id": ["48a77564d88ca8a893610b9458bfd885"],
    "X-Scheme": ["https"]
  },
  "hostname": "camarero-cf7c95ccd-cz5lh",
  "envVariables": [
    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
    "HOSTNAME=camarero-cf7c95ccd-cz5lh",
    "YOSOY_SHOW_FILES=/etc/podinfo/labels,/etc/podinfo/annotations",
    "YOSOY_SHOW_ENVS=true",
    "KUBERNETES_SERVICE_PORT=443",
    "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
    "KUBERNETES_PORT=tcp://10.96.0.1:443",
    "KUBERNETES_PORT_443_TCP_PORT=443",
    "KUBERNETES_SERVICE_HOST=10.96.0.1",
    "KUBERNETES_PORT_443_TCP_PROTO=tcp",
    "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
    "HOME=/root"
  ],
  "files": {
    "/etc/podinfo/annotations": "kubernetes.io/config.seen=\"2021-08-24T15:12:19.555374430Z\"\nkubernetes.io/config.source=\"api\"",
    "/etc/podinfo/labels": "app.kubernetes.io/component=\"api\"\napp.kubernetes.io/name=\"camarero\"\napp.kubernetes.io/part-of=\"hotel\"\napp.kubernetes.io/version=\"0.0.1\"\npod-template-hash=\"cf7c95ccd\""
  }
}

Sample ping/reachability analyzer responses

To test if yosoy can connect to google.com on port 443 using default tcp network use the following command:

curl -v "http://localhost/_/yosoy/ping?h=google.com&p=443"
> GET /_/yosoy/ping?h=google.com&p=443 HTTP/1.1
> Host: localhost
> User-Agent: curl/7.86.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Fri, 17 Nov 2023 05:54:36 GMT
< Content-Length: 29
< Content-Type: text/plain; charset=utf-8
<
{"message":"ping succeeded"}

To see an unsuccessful response you may use localhost with some random port number:

curl -v "http://localhost/_/yosoy/ping?h=127.0.0.1&p=12345"
> GET /_/yosoy/ping?h=127.0.0.1&p=12345 HTTP/1.1
> Host: localhost
> User-Agent: curl/7.86.0
> Accept: */*
>
< HTTP/1.1 500 Internal Server Error
< Date: Fri, 17 Nov 2023 05:53:48 GMT
< Content-Length: 66
< Content-Type: text/plain; charset=utf-8
<
{"error":"dial tcp 127.0.0.1:12345: connect: connection refused"}

Building and testing locally

Here are some commands to get you started.

Run yosoy directly on port 80.

go test -coverprofile cover.out
go tool cover -html=cover.out
go run server.go

Building local Docker container and run it on port 8080:

docker build -t yosoy-local:latest .
docker run --rm --name yosoy-local -p 8080:80 yosoy-local:latest

yosoy's People

Contributors

dependabot[bot] avatar lukaszbudnik avatar lukaszbudniktr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

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.