|
| 1 | +# Coding Standards |
| 2 | + |
| 3 | +This document outlines the coding standards and conventions used in the terraform-provider-elasticstack repository. |
| 4 | + |
| 5 | +## General Principles |
| 6 | + |
| 7 | +- Write idiomatic Go. |
| 8 | + - [Effective Go](https://go.dev/doc/effective_go) |
| 9 | + - [Code Review Comments](https://go.dev/wiki/CodeReviewComments) |
| 10 | + - The [Google Styleguide](https://google.github.io/styleguide/go/index#about) |
| 11 | + |
| 12 | +## Project Structure |
| 13 | + |
| 14 | +- Use the Plugin Framework for all new resources (not SDKv2) |
| 15 | +- Follow the code organization pattern of `internal/elasticsearch/security/system_user` for new Plugin Framework resources |
| 16 | +- Avoid adding extra functionality to the existing `utils` package. Instead: |
| 17 | + - Code should live as close the consumers. |
| 18 | + - Resource, area, application specific shared logic should live at that level. For example within `internal/kibana` for Kibana specific shared logic. |
| 19 | + - Provider wide shared logic should be packaged together by a logical concept. For example `internal/diagutil` contains shared code for managing Terraform Diagnostics, and translating between errors, SDKv2 diags, and Plugin Framework diags. |
| 20 | + |
| 21 | +## Schema Definitions |
| 22 | + |
| 23 | +- Use custom types to model attribute specific behaviour. |
| 24 | + - Use `jsontypes.NormalizedType{}` custom type for string attributes containing JSON blobs. |
| 25 | + - Use `customtypes.DurationType{}` for duration-based string attributes. |
| 26 | + - Use `customtypes.JSONWithDefaultsType{}` to allow users to specify only a subset of a JSON blob. |
| 27 | +- Always include comprehensive descriptions for all resources, and attributes. |
| 28 | +- Long, multiline descriptions should be stored in an external markdown file, which is imported via Golang embedding. See `resource-description.md` for examples. |
| 29 | +- Use schema validation wherever possible. Only perform validation within create/read/update functions as a last resort. |
| 30 | + - For example, any validation that relies on the actual Elastic Stack components (e.g Elasticsearch version) |
| 31 | + can only be performed during the create/read/update phase. |
| 32 | + |
| 33 | +## JSON Handling |
| 34 | + |
| 35 | +- Use `jsontypes.NormalizedType{}` for JSON string attributes to ensure proper normalization and comparison. |
| 36 | +- Use `customtypes.JSONWithDefaultsType{}` if API level defaults may be applied automatically. |
| 37 | + |
| 38 | +## Resource Implementation |
| 39 | + |
| 40 | +- Follow the pattern: `resource.go`, `schema.go`, `models.go`, `create.go`, `read.go`, `update.go`, `delete.go` |
| 41 | +- Use factory functions like `NewSystemUserResource()` to create resource instances |
| 42 | +- Ensure appropriate interface assertions are included alongside the resource definition. |
| 43 | + - For example, if a resource supports imports, include `var _ resource.ResourceWithImportState = &resource{}` or similar. |
| 44 | +- Prefer using existing util functions over longer form, duplicated code: |
| 45 | + - `utils.IsKnown(val)` instead of `!val.IsNull() && !val.IsUnknown()` |
| 46 | + - `utils.ListTypeAs` instead of `val.ElementsAs` or similar for other collection types |
| 47 | + |
| 48 | +## Testing |
| 49 | + |
| 50 | +- Use table-driven unit tests when possible with `t.Run()` for test cases |
| 51 | +- Use testify library (`assert`, `require`) for test assertions |
| 52 | +- Ensure that *every* resource attribute is covered by at least one acceptance test case whenever possible. |
| 53 | + - Features that *require* external services are likely the only excuse to not include acceptance test coverage. |
| 54 | +- Organize acceptance tests in `acc_test.go` files |
| 55 | +- Test Terraform code should be vanilla, valid Terraform |
| 56 | + - Store test Terraform modules in `testdata/<test_name>/<step_description>` directories. |
| 57 | + - Define any required variables within the module |
| 58 | + - Reference the test code via `ConfigDirectory: acctest.NamedTestCaseDirectory("<step description>")` |
| 59 | + - Define any required variables via `ConfigVariables` |
| 60 | + |
| 61 | +## API Client Usage |
| 62 | + |
| 63 | +- Use generated API clients from `generated/kbapi/` for new Kibana API interactions |
| 64 | +- Avoid deprecated clients (`libs/go-kibana-rest`, `generated/alerting`, `generated/connectors`, `generated/slo`) |
0 commit comments