{"id":50464391,"url":"https://github.com/martishin/kubebuilder-timoni-k8s-operator","last_synced_at":"2026-06-01T06:31:47.952Z","repository":{"id":315424693,"uuid":"1053748144","full_name":"martishin/kubebuilder-timoni-k8s-operator","owner":"martishin","description":"Kubernetes operator built with Kubebuilder, packaged \u0026 deployed using Timoni","archived":false,"fork":false,"pushed_at":"2025-09-28T04:14:28.000Z","size":310,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-17T06:39:41.514Z","etag":null,"topics":["kubebuilder","kubernetes","timoni"],"latest_commit_sha":null,"homepage":"","language":"CUE","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/martishin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2025-09-09T21:54:33.000Z","updated_at":"2025-09-28T04:14:31.000Z","dependencies_parsed_at":"2025-09-18T15:37:57.875Z","dependency_job_id":"b6699509-7ab0-4253-8a51-02541896b582","html_url":"https://github.com/martishin/kubebuilder-timoni-k8s-operator","commit_stats":null,"previous_names":["martishin/my-k8s-operator","martishin/kubebuilder-timoni-k8s-operator"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/martishin/kubebuilder-timoni-k8s-operator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martishin%2Fkubebuilder-timoni-k8s-operator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martishin%2Fkubebuilder-timoni-k8s-operator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martishin%2Fkubebuilder-timoni-k8s-operator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martishin%2Fkubebuilder-timoni-k8s-operator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/martishin","download_url":"https://codeload.github.com/martishin/kubebuilder-timoni-k8s-operator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martishin%2Fkubebuilder-timoni-k8s-operator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33763648,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["kubebuilder","kubernetes","timoni"],"created_at":"2026-06-01T06:31:46.356Z","updated_at":"2026-06-01T06:31:47.947Z","avatar_url":"https://github.com/martishin.png","language":"CUE","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kubebuilder + Timoni Kubernetes Operator\n\nA simple Kubernetes Operator (built with Kubebuilder) that reconciles a\n**Guestbook** custom resource (`webapp.my.domain/v1, Kind=Guestbook`).  \nFor each `Guestbook`, the controller creates and maintains a matching\n`Deployment` and `Service` (image, replicas, and port come from the spec)\nand reports readiness via `.status.conditions` and `.status.readyReplicas`.\n\nThe project is **packaged and deployed with Timoni**. Kubebuilder’s\nkustomize manifests remain for development/CI codegen, but Timoni is\nauthoritative for installs and upgrades.\n\n---\n\n## Table of contents\n\n- [Description](#description)\n- [Prerequisites](#prerequisites)\n- [Build \u0026 Release (Timoni-first)](#build--release-timoni-first)\n  - [Quick start on Kind (local)](#quick-start-on-kind-local)\n  - [Preview, apply, status](#preview-apply-status)\n  - [Test reconciliation](#test-reconciliation)\n  - [Uninstall](#uninstall)\n- [Local development](#local-development)\n  - [Run the controller locally](#run-the-controller-locally)\n  - [Unit/Envtest \u0026 e2e](#unitenvtest--e2e)\n- [Project structure](#project-structure)\n- [Legacy kustomize (optional)](#legacy-kustomize-optional)\n- [Contributing](#contributing)\n- [License](#license)\n\n---\n\n## Description\n\n**Goal of the controller**  \nThe controller watches `Guestbook` resources and continuously reconciles the\ndesired state:\n- Creates/updates a `Deployment` named `\u003cguestbook-name\u003e-deploy` using\n  `.spec.image`, `.spec.replicas`, and exposing `.spec.port`.\n- Creates/updates a `Service` named `\u003cguestbook-name\u003e-svc` targeting the pods.\n- Updates `.status.readyReplicas` and a `Ready` condition to reflect availability.\n\nThis demonstrates the **controller pattern**: a control loop compares desired\nstate (the CR spec) with actual cluster state and makes incremental changes until\nthey match.\n\n---\n\n## Prerequisites\n\n- **Go** `\u003e= 1.24`\n- **Docker** `\u003e= 17.03`\n- **kubectl** `\u003e= 1.24` (any reasonably recent version is fine)\n- **Timoni** CLI (install from https://timoni.sh/)\n- Access to a Kubernetes cluster (Kind, k3d, GKE, etc.). Examples below use **Kind**.\n\nOptional for tests:\n- **Kind** CLI (for e2e target)\n- **make**\n\n---\n\n## Build \u0026 Release (Timoni-first)\n\nAll Timoni artifacts live under `timoni/`. The main bundle is:\n```\ntimoni/bundles/operator-stack.cue\n```\nIt includes three instances:\n1. **crds** – the Guestbook CRD\n2. **operator** – the controller (RBAC, SA, Deployment, metrics svc, etc.)\n3. **sample** – a sample `Guestbook` resource\n\n### Quick start on Kind (local)\n\nIf you already have a Kind cluster named `myclaster`, skip the create step.\n\n```bash\n# 1) (Optional) Create a Kind cluster\nkind create cluster --name myclaster\n\n# 2) Build the controller image\nmake docker-build IMG=controller:dev\n\n# 3) Load the image into Kind\nmake kind-load IMG=controller:dev KIND_CLUSTER=myclaster\n\n# 4) Point the Timoni bundle to that image (in-place edit)\nmake bundle-set-image IMG=controller:dev\n\n# 5) Apply everything with Timoni\nmake bundle-apply\n```\n\n\u003e Tip: You can do steps (2)–(5) in one shot with:\n\u003e ```bash\n\u003e make release-local IMG=controller:dev KIND_CLUSTER=myclaster\n\u003e ```\n\n### Preview, apply, status\n\n```bash\n# Preview the generated manifests (no changes to the cluster)\nmake bundle-build | less\n\n# Diff vs the live cluster\nmake bundle-diff\n\n# Apply and wait for readiness\nmake bundle-apply\n\n# Check operator’s Timoni status and Kubernetes resources\nmake bundle-status\nkubectl -n tutorial-operator-system get deploy,pods\nkubectl get crd guestbooks.webapp.my.domain\n```\n\n### Test reconciliation\n\nCreate/update the sample CR (already applied by the bundle). Check that the\ncontroller creates the app resources and updates status.\n\n```bash\n# Verify the app Deployment+Service exist\nkubectl get deploy,svc -l app.kubernetes.io/part-of=guestbook -A\n\n# Inspect Guestbook status (expect Ready=True once replicas are available)\nkubectl get guestbook guestbook-sample -o yaml | yq '.status'\n```\n\nScale the CR and watch the Deployment change and status update:\n\n```bash\n# Scale from 2 -\u003e 3 replicas\nkubectl patch guestbook guestbook-sample --type=merge -p '{\"spec\":{\"replicas\":3}}'\n\n# Watch rollout\nkubectl -n default rollout status deploy/guestbook-sample-deploy\n\n# Verify the controller reported readiness\nkubectl get guestbook guestbook-sample -o yaml | yq '.status'\n```\n\nOptional: port-forward and browse the nginx page managed by the controller:\n\n```bash\nkubectl -n default port-forward svc/guestbook-sample-svc 8080:80\n# Open http://localhost:8080\n```\n\n### Uninstall\n\nDelete the whole stack with Timoni (CRDs, operator, sample CR):\n\n```bash\nmake bundle-delete\n```\n\nIf you only want to remove the sample CR (and keep the operator):\n\n```bash\n$(TIMONI) apply -n default sample --module timoni/modules/guestbook-sample --prune --delete\n```\n\n---\n\n## Local development\n\n### Run the controller locally\n\nRun the controller against your current kubecontext (no image build needed).\n\n```bash\nmake run\n```\n\nYou can then create/update `Guestbook` resources and watch logs in your terminal.\n\n### Unit/Envtest \u0026 e2e\n\n```bash\n# Unit/integration tests (envtest)\nmake test\n\n# e2e tests (requires Kind)\nmake test-e2e\n```\n\n---\n\n## Project structure\n\n```\ntutorial-operator/\n├── api/v1/                      # CRD Go types (scheme, deepcopy, etc.)\n├── cmd/main.go                  # Controller entrypoint\n├── internal/controller/         # Reconciler implementation\n├── timoni/\n│   ├── bundles/operator-stack.cue\n│   └── modules/\n│       ├── tutorial-operator-crds/   # CRD instance\n│       ├── tutorial-operator/        # Operator instance (RBAC, SA, Deployment, metrics)\n│       └── guestbook-sample/         # Sample Guestbook instance\n└── config/                     # Kubebuilder kustomize (kept for dev/CI, not used to deploy)\n```\n\n\u003e **Note:** `config/` (kustomize) is not used by Timoni. If you keep it in the\nrepo (recommended), add a short README to `config/` stating:\n“Not used for deployment; Timoni is authoritative.”\n\n---\n\n## Legacy kustomize (optional)\n\nIf you still want a single YAML bundle (e.g., for troubleshooting), you can render it:\n\n```bash\nmake build-installer IMG=controller:dev\n# outputs dist/install.yaml\nkubectl apply -f dist/install.yaml\n```\n\nFor production, prefer **Timoni** for installing and upgrading.\n\n---\n\n## Contributing\n\nPRs welcome! Please run linters and tests locally:\n\n```bash\nmake lint\nmake test\n```\n\nRun `make help` to see all available targets.\n\n---\n\n## License\n\nCopyright 2025.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartishin%2Fkubebuilder-timoni-k8s-operator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmartishin%2Fkubebuilder-timoni-k8s-operator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartishin%2Fkubebuilder-timoni-k8s-operator/lists"}