원클릭으로
cr-field
// Use when adding a new field to an existing Custom Resource. Guides the full workflow: API types, code generation, CRD examples, client investigation, handler mapping, and tests.
// Use when adding a new field to an existing Custom Resource. Guides the full workflow: API types, code generation, CRD examples, client investigation, handler mapping, and tests.
| name | cr-field |
| description | Use when adding a new field to an existing Custom Resource. Guides the full workflow: API types, code generation, CRD examples, client investigation, handler mapping, and tests. |
| allowed-tools | Bash(make *), Read, Grep, Glob |
Add a new field to an existing Custom Resource following the project's established conventions. Work through all steps in order. Do not skip steps.
File: api/v1/{kind}_types.go (or api/v1alpha1/ for alpha resources).
Add the struct field with a godoc comment and kubebuilder markers. Choose markers that match the field's semantics:
// +required / // +optional// +nullable — for pointer slices or maps that can be explicitly null// +kubebuilder:validation:Enum=val1;val2 — restrict to allowed values// +kubebuilder:default=value — set a default when field is omitted// +kubebuilder:example=value — example shown in generated docs// +kubebuilder:validation:XValidation:rule=...,message=... — CEL validation (e.g. immutability)JSON tag: json:"fieldName,omitempty" for optional fields, json:"fieldName" for required.
See api/v1/keycloakclient_types.go for the full variety of marker patterns in use.
make generate && make manifests
This regenerates DeepCopy methods and CRD YAMLs in config/crd/bases/ and deploy-templates/crds/.
Add the new field with a meaningful example value to:
config/samples/v1_v1_{kind}.yamldeploy-templates/_crd_examples/{kind}.yamlThis is the critical investigation step before touching any handler code.
All controllers use pkg/client/keycloakapi/. Confirm the handler imports this package.
Check pkg/client/keycloakapi/contracts.go for the relevant client interface
(GroupsClient, ClientsClient, RolesClient, etc.).
Representation types are type aliases — grep pkg/client/keycloakapi/generated/client_generated.go
for the struct name (e.g. GroupRepresentation, ClientRepresentation, RoleRepresentation)
to see which fields are available.
openapi.yaml is auto-generated and must not be edited manually. Ask the user how to proceed before making any further changes.In internal/controller/{resource}/chain/ find the handler that creates/updates the resource
(usually create_or_update_{resource}.go or put_{resource}.go).
Map the field in both paths:
Reference: internal/controller/keycloakrealmgroup/chain/create_or_update_group.go
File: internal/controller/{resource}/chain/*_test.go
Add the field to the spec setup and to the mock expectations for all test cases: create path, update path, and error paths.
Reference: internal/controller/keycloakrealmgroup/chain/create_or_update_group_test.go
File: internal/controller/{resource}/*_controller_integration_test.go
Add the field to the CR creation spec. Assert the correct value is persisted in Keycloak
using Eventually() + g.Expect().
Reference: internal/controller/keycloakrealmgroup/keycloakrealmgroup_controller_integration_test.go
Invoke the run-golangci-lint skill, then the run-tests skill.
Use when generating testify mocks for an interface. Ensures the interface is registered in .mockery.yml, runs make mocks, and verifies the output file.
Run tests for the edp-keycloak-operator. By default runs unit + integration tests. Use /run-tests e2e for end-to-end tests.
Run golangci-lint linters and fix any linting errors. Use when fixing lint issues or before committing code.