{"id":15288870,"url":"https://github.com/lukaszbudnik/yosoy","last_synced_at":"2025-04-13T08:11:37.558Z","repository":{"id":37535754,"uuid":"312588131","full_name":"lukaszbudnik/yosoy","owner":"lukaszbudnik","description":"yosoy is an HTTP service for stubbing and prototyping distributed applications.","archived":false,"fork":false,"pushed_at":"2024-03-01T17:57:32.000Z","size":109,"stargazers_count":12,"open_issues_count":4,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-27T00:05:38.934Z","etag":null,"topics":["distributed-systems","docker","docker-image","go","golang","kubernetes","ping","prototyping","reachability-analysis","stubbing"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lukaszbudnik.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["lukaszbudnik"]}},"created_at":"2020-11-13T13:48:51.000Z","updated_at":"2024-10-23T14:12:38.000Z","dependencies_parsed_at":"2024-06-19T05:24:28.595Z","dependency_job_id":"58503a13-0b5e-47a6-b6ed-3aefb26219d8","html_url":"https://github.com/lukaszbudnik/yosoy","commit_stats":{"total_commits":44,"total_committers":3,"mean_commits":"14.666666666666666","dds":0.5,"last_synced_commit":"68691a718aaff63257601ac09c39609c4dff6eba"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukaszbudnik%2Fyosoy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukaszbudnik%2Fyosoy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukaszbudnik%2Fyosoy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukaszbudnik%2Fyosoy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lukaszbudnik","download_url":"https://codeload.github.com/lukaszbudnik/yosoy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248681497,"owners_count":21144700,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["distributed-systems","docker","docker-image","go","golang","kubernetes","ping","prototyping","reachability-analysis","stubbing"],"created_at":"2024-09-30T15:53:56.238Z","updated_at":"2025-04-13T08:11:37.535Z","avatar_url":"https://github.com/lukaszbudnik.png","language":"Go","funding_links":["https://github.com/sponsors/lukaszbudnik"],"categories":[],"sub_categories":[],"readme":"# yosoy ![Go](https://github.com/lukaszbudnik/yosoy/workflows/Go/badge.svg) ![Docker](https://github.com/lukaszbudnik/yosoy/workflows/Docker%20Image%20CI/badge.svg)\n\nyosoy 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. \n\nyosoy 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.\n\nTypical use cases include:\n\n- Testing HTTP routing and ingress\n- Testing HTTP load balancing\n- Testing HTTP caching\n- Executing reachability analysis\n- Stubbing and prototyping distributed applications\n\n\"Yo soy\" means \"I am\" in Spanish.\n\n## API\n\nyosoy responds to all requests with a JSON containing the information about:\n\n- HTTP request:\n  - Host\n  - Request URI\n  - Method\n  - Scheme\n  - Proto\n  - URL\n  - Remote IP\n  - HTTP headers\n  - HTTP proxy headers\n- host:\n  - Hostname\n  - How many times it was called\n  - Env variables if `YOSOY_SHOW_ENVS` is set to `true`, `yes`, `on`, or `1`\n  - Files' contents if `YOSOY_SHOW_FILES` is set to a comma-separated list of (valid) files\n\nCheck [Sample JSON response](#sample-json-response) to see how you can use yosoy for stubbing/prototyping/troubleshooting distributed applications.\n\n## ping/reachability analyzer\n\nyosoy 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:\n\n* `h` - required - hostname of the endpoint\n* `p` - required - port of the endpoint\n* `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.\n* `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.\n\nCheck [Sample ping/reachability analyzer responses](#sample-pingreachability-analyzer-responses) to see how you can use yosoy for troubleshooting network connectivity.\n\n## Docker image\n\nThe docker image is available on docker hub and ghcr.io:\n\n```sh\ndocker pull lukasz/yosoy\ndocker pull ghcr.io/lukaszbudnik/yosoy\n```\n\nIt exposes HTTP service on port 80.\n\n## Kubernetes example\n\nThere 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.\n\nDeploy it to minikube and execute curl to the service a couple of times:\n\n```bash\n# start minikube\nminikube start\n# deploy test service\nkubectl apply -f test/deployment.yaml\n# tunnel to it and copy the URL as $URL variable\nminikube service --url camarero\n# simulate some HTTP requests\ncurl -H \"Host: gateway.myapp.com\" $URL/camarero/abc\ncurl -H \"Host: gateway.myapp.com\" $URL/camarero/abc\ncurl -H \"Host: gateway.myapp.com\" $URL/camarero/abc\ncurl -H \"Host: gateway.myapp.com\" $URL/camarero/abc\n```\n\n## Sample JSON response\n\nA 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](https://github.com/lukaszbudnik/haproxy-auth-gateway) looks like this:\n\n```json\n{\n  \"host\": \"api.localtest.me\",\n  \"proto\": \"HTTP/1.1\",\n  \"method\": \"GET\",\n  \"scheme\": \"https\",\n  \"requestUri\": \"/camarero\",\n  \"url\": \"https:///camarero\",\n  \"remoteAddr\": \"192.168.65.3\",\n  \"counter\": 1,\n  \"headers\": {\n    \"Accept\": [\"*/*\"],\n    \"Accept-Encoding\": [\"gzip, deflate, br\"],\n    \"Accept-Language\": [\"en-US,en;q=0.9,pl-PL;q=0.8,pl;q=0.7,es;q=0.6\"],\n    \"Authorization\": [\n      \"Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJXejFuaDNCWDI4UHMxVEMzSDRoOW52Q1VWRXpjVVBzQms4Z1NmeEp4ZS1JIn0.eyJleHAiOjE2Mjk4MjM3OTMsImlhdCI6MTYyOTgyMjg5MywiYXV0aF90aW1lIjoxNjI5ODIyODkyLCJqdGkiOiI3ZmQzMjkwZi05NjMyLTQ0NzEtYjRjOS1lNTFjZDYwMjllYjgiLCJpc3MiOiJodHRwczovL2F1dGgubG9jYWx0ZXN0Lm1lL2F1dGgvcmVhbG1zL2hvdGVsIiwic3ViIjoiMDdmYzM3YmYtMmJjNy00ZTRmLWE3MDUtYzRjNjgzNTIwYmU1IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoicmVhY3QiLCJub25jZSI6IjQzNDhmMjU5LTliYTYtNDk2ZC04N2I5LWZmZGYzNDMwN2UzOSIsInNlc3Npb25fc3RhdGUiOiJmNTM5OGI3Ny01OTNhLTQ3OWYtOTc5NS00NGIyNGJjMjhkYjQiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbImh0dHBzOi8vbHVrYXN6YnVkbmlrLmdpdGh1Yi5pbyJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiY2FtYXJlcm8iXX0sInNjb3BlIjoib3BlbmlkIGVtYWlsIHByb2ZpbGUiLCJzaWQiOiJmNTM5OGI3Ny01OTNhLTQ3OWYtOTc5NS00NGIyNGJjMjhkYjQiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJKdWxpbyIsInByZWZlcnJlZF91c2VybmFtZSI6Imp1bGlvIiwiZ2l2ZW5fbmFtZSI6Ikp1bGlvIn0.t5y3L4FzGxM0zwI3fskDI8Kemxz_izcvPPKciSEvNHnZWGQK-9AclGNFz_A9cLFSkpc6l6lBmt7WaC0i04c4h1a9G9AOFImmVXPMPDdTXOQ4aah4CvlN6Fy8ShvSHrQA-wMHEELBpIFsKFx2WP3QHiy27ycr3kqQzW4QymyU7J8tM4-qKR_H1_8aiNOrm5fIED-nEP096V2zvWXiGZX7ts6XE2-annhKphCABLdmIiwgDUnhlAz0hdiDrDbIjzr0ldW4AnUkSQxIZY0PnoEnGVuUvkOYvJpFx10gjORMnRgHSEj9Mk5dtyVGHcihZ5TntCL40WoymNxae6K4-FH3Lw\"\n    ],\n    \"Origin\": [\"https://lukaszbudnik.github.io\"],\n    \"Referer\": [\"https://lukaszbudnik.github.io/\"],\n    \"Sec-Ch-Ua\": [\n      \"\\\" Not;A Brand\\\";v=\\\"99\\\", \\\"Google Chrome\\\";v=\\\"91\\\", \\\"Chromium\\\";v=\\\"91\\\"\"\n    ],\n    \"Sec-Ch-Ua-Mobile\": [\"?0\"],\n    \"Sec-Fetch-Dest\": [\"empty\"],\n    \"Sec-Fetch-Mode\": [\"cors\"],\n    \"Sec-Fetch-Site\": [\"cross-site\"],\n    \"User-Agent\": [\n      \"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\"\n    ],\n    \"X-Forwarded-For\": [\"192.168.65.3\", \"10.1.3.9\"],\n    \"X-Forwarded-Host\": [\"api.localtest.me\"],\n    \"X-Forwarded-Port\": [\"443\"],\n    \"X-Forwarded-Proto\": [\"https\"],\n    \"X-Real-Ip\": [\"192.168.65.3\"],\n    \"X-Request-Id\": [\"48a77564d88ca8a893610b9458bfd885\"],\n    \"X-Scheme\": [\"https\"]\n  },\n  \"hostname\": \"camarero-cf7c95ccd-cz5lh\",\n  \"envVariables\": [\n    \"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\n    \"HOSTNAME=camarero-cf7c95ccd-cz5lh\",\n    \"YOSOY_SHOW_FILES=/etc/podinfo/labels,/etc/podinfo/annotations\",\n    \"YOSOY_SHOW_ENVS=true\",\n    \"KUBERNETES_SERVICE_PORT=443\",\n    \"KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443\",\n    \"KUBERNETES_PORT=tcp://10.96.0.1:443\",\n    \"KUBERNETES_PORT_443_TCP_PORT=443\",\n    \"KUBERNETES_SERVICE_HOST=10.96.0.1\",\n    \"KUBERNETES_PORT_443_TCP_PROTO=tcp\",\n    \"KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1\",\n    \"HOME=/root\"\n  ],\n  \"files\": {\n    \"/etc/podinfo/annotations\": \"kubernetes.io/config.seen=\\\"2021-08-24T15:12:19.555374430Z\\\"\\nkubernetes.io/config.source=\\\"api\\\"\",\n    \"/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\\\"\"\n  }\n}\n```\n\n## Sample ping/reachability analyzer responses\n\nTo test if yosoy can connect to `google.com` on port `443` using default `tcp` network use the following command:\n\n```bash\ncurl -v \"http://localhost/_/yosoy/ping?h=google.com\u0026p=443\"\n\u003e GET /_/yosoy/ping?h=google.com\u0026p=443 HTTP/1.1\n\u003e Host: localhost\n\u003e User-Agent: curl/7.86.0\n\u003e Accept: */*\n\u003e\n\u003c HTTP/1.1 200 OK\n\u003c Date: Fri, 17 Nov 2023 05:54:36 GMT\n\u003c Content-Length: 29\n\u003c Content-Type: text/plain; charset=utf-8\n\u003c\n{\"message\":\"ping succeeded\"}\n```\n\nTo see an unsuccessful response you may use localhost with some random port number:\n\n```bash\ncurl -v \"http://localhost/_/yosoy/ping?h=127.0.0.1\u0026p=12345\"\n\u003e GET /_/yosoy/ping?h=127.0.0.1\u0026p=12345 HTTP/1.1\n\u003e Host: localhost\n\u003e User-Agent: curl/7.86.0\n\u003e Accept: */*\n\u003e\n\u003c HTTP/1.1 500 Internal Server Error\n\u003c Date: Fri, 17 Nov 2023 05:53:48 GMT\n\u003c Content-Length: 66\n\u003c Content-Type: text/plain; charset=utf-8\n\u003c\n{\"error\":\"dial tcp 127.0.0.1:12345: connect: connection refused\"}\n```\n\n## Building and testing locally\n\nHere are some commands to get you started.\n\nRun yosoy directly on port 80.\n\n```bash\ngo test -coverprofile cover.out\ngo tool cover -html=cover.out\ngo run server.go\n```\n\nBuilding local Docker container and run it on port 8080:\n\n```bash\ndocker build -t yosoy-local:latest .\ndocker run --rm --name yosoy-local -p 8080:80 yosoy-local:latest\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukaszbudnik%2Fyosoy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flukaszbudnik%2Fyosoy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukaszbudnik%2Fyosoy/lists"}