{"id":15130073,"url":"https://github.com/yandex/protoc-gen-crd","last_synced_at":"2025-07-24T12:02:07.354Z","repository":{"id":247412053,"uuid":"823523682","full_name":"yandex/protoc-gen-crd","owner":"yandex","description":"Protobuf plugin for generating k8s CRD ","archived":false,"fork":false,"pushed_at":"2025-05-24T08:05:11.000Z","size":121,"stargazers_count":25,"open_issues_count":1,"forks_count":0,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-05-24T09:19:04.692Z","etag":null,"topics":["crd","iac","k8s","k8s-operator","protobuf"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yandex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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}},"created_at":"2024-07-03T07:43:00.000Z","updated_at":"2025-05-24T08:05:14.000Z","dependencies_parsed_at":"2025-04-15T12:46:36.327Z","dependency_job_id":null,"html_url":"https://github.com/yandex/protoc-gen-crd","commit_stats":null,"previous_names":["yandex/protoc-gen-crd"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/yandex/protoc-gen-crd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yandex%2Fprotoc-gen-crd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yandex%2Fprotoc-gen-crd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yandex%2Fprotoc-gen-crd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yandex%2Fprotoc-gen-crd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yandex","download_url":"https://codeload.github.com/yandex/protoc-gen-crd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yandex%2Fprotoc-gen-crd/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266839146,"owners_count":23993052,"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","status":"online","status_checked_at":"2025-07-24T02:00:09.469Z","response_time":99,"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":["crd","iac","k8s","k8s-operator","protobuf"],"created_at":"2024-09-26T02:29:01.073Z","updated_at":"2025-07-24T12:02:07.273Z","avatar_url":"https://github.com/yandex.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"protoc-gen-crd\n==============\n\nprotoc-gen-crd is a protobuf compiler plugin to generate Kubernetes YAML spec for CRD from protobuf definition.\n\nIt is used to simplify creating and maintaing Kubernetes CRD schemas. Key features:\n\n- Human-readable and human-writable. Protobuf is user friendly, K8s flavored OpenAPI is definitely not.\n- Composable. K8s flavored OpenAPI denies even `$ref` between document parts, let alone references between multiple schemas.\n  Protobuf allows you to split schema into multiple files, import external schema parts, and compose them as you wish.\n- Schema versioning replaced with protobuf backward compatibility guidelines. Forget about dealing with multiple structures\n  and conversion functions, use single protobuf message.\n- Two modes: permissive server one and strict client one with support of client-only fields.\n- The same protobuf files may be used to generate code in any language.\n\nJust annotate single message in a proto-file with our special annotation, and compile it using this plugin.\n\nRequirements\n------------\n\n- [Go](https://golang.org/doc/install) 1.22 (to build the plugin)\n- [Protobuf compiler](https://github.com/protocolbuffers/protobuf/releases/latest)\n\nInstallation\n------------\n\nTo install plugin, run the following command:\n\n```sh\n$ go install github.com/yandex/protoc-gen-crd/cmd/protoc-gen-crd@latest\n```\n\nUsage\n-----\n\nFirst, you need to add protobuf file  `proto/mycrd.proto` with the CRD annotations into your project:\n\n```protobuf\nimport \"github.com/yandex/protoc-gen-crd/library/go/k8s/protoc_gen_crd/proto/crd.proto\";\n\noption go_package = \"example.com/m/proto\";\n\nmessage Spec {\n    // your fields\n}\n\nmessage Status {\n    // your fields\n}\n\nmessage MyCrdKind {\n    option (protoc_gen_crd.k8s_crd) = {\n           api_group: \"my-api.my-company.org\",\n           kind: \"MyCrdKind\",\n           plural: \"mycrdkinds\",\n           singular: \"mycrdkind\",\n           short_names: [\"mck\", \"mycrd\"],\n           categories: [\"coolstuff\", \"my-company\"],\n           additional_columns: [\n               {\n                   name: \"Gen\",\n                   type: CT_INTEGER,\n                   description: \"Object generation\",\n                   json_path: \".metadata.generation\",\n               },\n           ]\n    };\n\n    Spec spec = 1;\n    Status status = 2;\n}\n\n```\n\nOption fields `api_group`, `kind`, `plural`, and `singular` are mandatory. Other ones can be omitted.\nFor more information about supported fields see comments in `library/go/k8s/protoc_gen_crd/proto/crd.proto`.\n\nThen compile proto file into YAML using installed protoc-gen-crd plugin:\n\n```sh\n$ protoc -I=proto -I=vendor --crd_out=paths=source_relative:./proto mycrd.proto\n```\n\nThis will give you `proto/mycrd.crd.yaml`, which can be put with `kubectl apply -f proto/mycrd.crd.yaml`.\n\nAlso see full example with protobuf and Makefile in the `example/` subdirectory.\n\nKustomize patch hints\n---------------------\n\nOptionally you can specify kustomize patch parameters via special annotation:\n\n```protobuf\nmessage Spec {\n    repeated MyField my_fields = 1 [(protoc_gen_crd.k8s_patch) = {\n        merge_key: \"some_key\",\n        merge_strategy: \"merge\",\n    }];\n}\n```\n\nThe other way to specify patch parameters is to specify them as part of protoc_gen_crd.k8s_crd option:\n\n```protobuf\nmessage MyCrdKind {\n    option (protoc_gen_crd.k8s_crd) = {\n        api_group: \"my-api.my-company.org\",\n        kind: \"MyCrdKind\",\n        /* ... */\n        field_patch_strategies: [\n            {\n                // select some single field inside the MyCrdKind message.\n                field_path: \"spec.my_fields\",\n                k8s_patch: {\n                    merge_key: \"some_key\",\n                    merge_strategy: \"merge\",\n                }\n            },\n            {\n                // apply patch to all fields of the specified type.\n                protobuf_type: \"MyField\",\n                k8s_patch: {\n                    merge_key: \"some_key\",\n                    merge_strategy: \"merge\",\n                }\n            }\n        ]\n    };\n};\n```\n\nWhen some patch parameters conflict, precedence is the following: field-specific patch \u003e type-specific patch \u003e field annotation.\n\nSecond way is intended to use for external APIs that are imported into your own proto message, and cannot be modified.\n\nTo build client version of the schema, add option `--crd_opt=client-schema=true` into your `protoc` command invocation.\n\nAlso see full example with protobuf and Makefile in the `example/` subdirectory.\n\nStrict schema\n------------------------\n\nBy default CRDs are permissive and allow unknown object fields (`additionalProperties: true` in json schema)\nto enable protobuf compatibility with future schema versions. You can change this behavior with `--crd_opt=strict-schema=true` option.\n\nClient schema and fields\n------------------------\n\nBy default CRDs are compiled in server mode, but you can enable client mode with `--crd_opt=client-schema=true` option.\n\nKey differces between modes:\n\n1. Strict schema is enabled because client always operates with known protobuf version.\n2. Client mode allows to mark some fields as client-only, so that they would be processed on the client, but should not exist on server.\n\n\u003e [!TIP]\n\u003e Unfortunately, kustomize can't merge fields without explicitly specified merge keys. If you can't or don't want to create merge keys manually, `protoc-gen-crd` can add fake merge key to your client schema. To enable add the option `--crd_opt=generate-merge-keys=true`. You still need to fill these keys by yourself.\n\nSchemaless CRD\n------------------------\n\nIf you need to validate a custom resource with your own tools, you can replace CRD schema on the server by opaque object. In this case, K8S will save all unknown fields inside \"spec\" and \"status\", but will still validate common fields required for correct k8s operations (metadata, kind, apiVersion).\n\nTo generate such a scheme, add the option `--crd_opt=schemaless=true`\n\nKnown caveats\n-------------\n\n### oneOf\n\nProtobuf `oneof` and OpenAPI `oneOf` have different semantics.\nIn protobuf `oneof` denotes just a single group of alternatives, and you may have as many groups as you wish.\nIn OpenAPI it is a single property of the message that should list all possible combinations (Cartesian product).\n\nHence, the following protobuf message:\n```protobuf\nmessage M {\n    oneof group1 {\n        string s1 = 1;\n        string s2 = 2;\n    }\n    oneof group2 {\n        string s3 = 3;\n        string s4 = 4;\n    }\n}\n```\n\nWould become the following set of alternatives in OpenAPI:\n```yaml\noneOf:\n  - properties:\n      s1: ...\n      s3: ...\n  - properties:\n      s1: ...\n      s4: ...\n  - properties:\n      s2: ...\n      s3: ...\n  - properties:\n      s2: ...\n      s4: ...\n  - properties:\n      s1: ...\n  - properties:\n      s2: ...\n  - properties:\n      s3: ...\n  - properties:\n      s4: ...\n  - properties: {}\n```\n\nAnd on top of that Kubernetes requires for all properties inside `oneOf` [to be repeated][structural schema] outside of it.\n\nSince this would effectively lead to [combinatorial explosion][combinatorial explosion], protobuf `oneof`s are NOT marked\nin CRD in any way, and just rendered like a set of optional fields. Currently one should validate `oneof`s with validation\nwebhook or something similar: just parse the message as protobuf object and catch errors if any.\n\n### Recursive structures\n\nProtobuf allows structures to reference themselves, effectively making recursive structure, e.g.:\n\n```protobuf\nmessage M {\n    M inner = 1;\n}\n```\n\nWhile this also is possible in vanilla OpenAPI, kubernetes implementation [forbids][schema validation] any definition `$ref`s.\n\nTo deal with this limitation at the points of recursion we mark nested objects as opaque with unknown structure:\n```yaml\nproperties:\n  inner:\n    type: object\n    x-kubernetes-preserve-unknown-fields: true\n```\n\nAgain, you are recommended to use validation webhook which would parse your object as protobuf message to check its schema.\n\n[structural schema]: https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema\n[schema validation]: https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation\n[combinatorial explosion]: https://en.wikipedia.org/wiki/Combinatorial_explosion\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyandex%2Fprotoc-gen-crd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyandex%2Fprotoc-gen-crd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyandex%2Fprotoc-gen-crd/lists"}