{"id":31561796,"url":"https://github.com/ruanbekker/kindly-api","last_synced_at":"2026-05-04T13:34:29.935Z","repository":{"id":265350977,"uuid":"864312398","full_name":"ruanbekker/kindly-api","owner":"ruanbekker","description":"KindlyAPI is a Flask-based API server designed to simplify the process of deploying, managing, and destroying Kubernetes clusters using Kind.","archived":false,"fork":false,"pushed_at":"2024-11-14T10:19:26.000Z","size":19,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-31T06:33:39.274Z","etag":null,"topics":["devops","devops-tools","docker","ephemeral-environments","flask","kind","kind-kubernetes","kubernetes","kubernetes-cluster","python","python-docker","python-flask"],"latest_commit_sha":null,"homepage":"https://ruan.dev","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ruanbekker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-09-27T23:08:50.000Z","updated_at":"2024-10-01T17:29:26.000Z","dependencies_parsed_at":null,"dependency_job_id":"a67be3c0-dabf-407f-be22-3bb5535f6156","html_url":"https://github.com/ruanbekker/kindly-api","commit_stats":null,"previous_names":["ruanbekker/kindly-api"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ruanbekker/kindly-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruanbekker%2Fkindly-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruanbekker%2Fkindly-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruanbekker%2Fkindly-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruanbekker%2Fkindly-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ruanbekker","download_url":"https://codeload.github.com/ruanbekker/kindly-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruanbekker%2Fkindly-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32609833,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-04T10:08:07.713Z","status":"ssl_error","status_checked_at":"2026-05-04T10:08:02.005Z","response_time":58,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["devops","devops-tools","docker","ephemeral-environments","flask","kind","kind-kubernetes","kubernetes","kubernetes-cluster","python","python-docker","python-flask"],"created_at":"2025-10-05T03:32:16.875Z","updated_at":"2026-05-04T13:34:29.929Z","avatar_url":"https://github.com/ruanbekker.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# kindly-api\n\n**KindlyAPI** is a Flask-based API server designed to simplify the process of deploying, managing, and destroying Kubernetes clusters using [Kind](https://kind.sigs.k8s.io/). The API allows users to interact over the network to create clusters, retrieve kubeconfig files, and clean up clusters after testing, making it ideal for environments where temporary Kubernetes clusters are required.\n\n### Features:\n\n- **Deploy Kubernetes Clusters**: Easily deploy new Kind clusters with a single API call.\n- **List Clusters**: View all running clusters managed by the API.\n- **Retrieve Kubeconfig**: Fetch the kubeconfig for a specific cluster to manage it remotely.\n- **Destroy Clusters**: Tear down clusters when they are no longer needed.\n\n### Requirements:\n\n- Docker\n- Kind\n- Python 3.11+\n- Flask\n\n---\n\n## Endpoints\n\n### 1. **List Clusters**\n   - **GET** `/clusters`\n   - Returns a list of active clusters.\n   - **Description**: Retrieves a list of currently deployed clusters along with their details (e.g., name, kubeconfig path, host port).\n   - **Example Request**:\n     ```bash\n     curl http://localhost:5000/clusters\n     ```\n   - **Example Response**:\n     ```bash\n     {\n        \"kind-abc123\": {\n          \"name\": \"kind-abc123\",\n          \"host_port\": 45001,\n          \"kubeconfig\": \"/tmp/kubeconfigs/kind-abc123-config.yaml\",\n          \"kindconfig\": \"/tmp/kubeconfigs/kind-abc123-kindconfig.yaml\"\n        }\n      }\n      ```\n\n### 2. **Deploy a Cluster**\n   - **POST** `/clusters/deploy`\n   - Deploys a new Kubernetes cluster using Kind.\n   - **Description**: Deploys a new Kind Kubernetes cluster. You can customize the deployment by specifying the number of nodes and the Kubernetes version. If no payload is provided, a single-node cluster with the default version is created.\n   - **Payload Options**:\n     - `nodes` (optional): The number of nodes to include in the cluster (default: 1).\n     - `version`: (optional): The Kubernetes version for the cluster (default: v1.28.0).\n   - **Example Request**: \n     - Deploy a default single-node cluster:\n       ```bash\n       curl -X POST http://localhost:5000/clusters/deploy\n       ```\n     - Deploy a cluster with 2 nodes:\n       ```bash\n       curl -X POST http://localhost:5000/clusters/deploy -d '{\"nodes\": 2}' -H \"Content-Type: application/json\"\n       ```\n     - Deploy a cluster with a specific Kubernetes version:\n       ```bash\n       curl -X POST http://localhost:5000/clusters/deploy -d '{\"version\": \"v1.28.13\"}' -H \"Content-Type: application/json\"\n       ```\n     - Deploy a cluster with 2 nodes and a specific Kubernetes version:\n       ```bash\n       curl -X POST http://localhost:5000/clusters/deploy -d '{\"nodes\": 2, \"version\": \"v1.28.13\"}' -H \"Content-Type: application/json\"\n       ``` \n   - **Example Response**:\n       ```json\n       {\n         \"message\": \"Cluster deployed\",\n         \"cluster_name\": \"kind-abc123\",\n         \"port\": 45001\n       }\n       ```\n\n### 3. **Retrieve Kubeconfig**\n   - **GET** `/clusters/kubeconfig/\u003ccluster-id\u003e`\n   - **Description**: Fetches the kubeconfig for the specified cluster.\n   - **Example Request**:\n     ```bash\n     curl -s http://localhost:5000/clusters/kubeconfig/kind-12345 | jq -r '.kubeconfig'\n     ```\n   - **Example Response**:\n     ```json\n     {\n       \"kubeconfig\": \"apiVersion: v1\\nclusters:\\n- cluster:\\n    certificate-authority-data: ...\"\n     }\n     ```\n\n### 4. **Destroy a Cluster**\n   - **DELETE** `/clusters/destroy/\u003ccluster-id\u003e`\n   - **Description**: Destroys the specified Kubernetes cluster.\n   - **Example Request**: \n     ```bash\n     curl -XDELETE http://localhost:5000/clusters/destroy/kind-abc123\n     ```\n   - **Example Response**:\n     ```json\n     {\n       \"message\": \"Cluster kind-abc123 destroyed\"\n     }\n     ```\n\n---\n\n## Getting Started\n\n### 1. Clone the repository:\n```bash\ngit clone https://github.com/ruanbekker/kindly-api.git\ncd kindly-api\n```\n\n### 2. Set up Docker and Docker Compose:\n\nEnsure you have Docker and Docker Compose installed and running.\n\n### 3. Build and Run the Application:\n\n```bash\ndocker compose up --build\n```\n\nThis will start the Flask API on port `5000`.\n\n### 4. Interact with the API:\n\nYou can now interact with the API using the endpoints listed above. For example, deploy a new cluster:\n\n```bash\ncurl -X POST http://localhost:5000/clusters/deploy\n```\n\n### 5. View Logs:\n\nTo view logs from the running containers, use:\n\n```bash\ndocker compose logs -f\n```\n\n### 6. Access using Kubectl:\n\nDump the kubeconfig using the cluster id:\n\n```bash\ncurl -s http://localhost:5000/clusters/kubeconfig/kind-8qta2 | jq -r '.kubeconfig' \u003e /tmp/.config\n```\n\nSet the `KUBECONFIG` environment variable to the file:\n\n```bash\nexport KUBECONFIG=/tmp/.config\n```\n\nAccess the cluster using kubectl:\n\n```bash\nkubectl get nodes\n# NAME                       STATUS   ROLES           AGE   VERSION\n# kind-8qta2-control-plane   Ready    control-plane   39s   v1.27.3\n```\n\n### 7. Destroy the Cluster:\n\nDestroy the cluster by providing the clusterid:\n\n```bash\ncurl -XDELETE http://localhost:5000/clusters/kubeconfig/kind-8qta2\n```\n\n---\n\n## Configuration\n\n- **NODE_IP_ADDRESS**: Set this environment variable in `docker-compose.yml` to match your host machine's IP address so that the kubeconfig files can be generated correctly for remote use.\n- **DOCKER_HOST**: This is set to `/var/run/docker.sock` to communicate with the Docker daemon.\n\n---\n\n## License\n\nThis project is licensed under the MIT License.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fruanbekker%2Fkindly-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fruanbekker%2Fkindly-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fruanbekker%2Fkindly-api/lists"}