|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +A [libdns](https://github.com/libdns/libdns) provider for Oracle Cloud Infrastructure (OCI) DNS. Single-package Go module (`package oraclecloud`) that implements `GetRecords`, `AppendRecords`, `SetRecords`, `DeleteRecords`, and `ListZones`. |
| 8 | + |
| 9 | +Module path: `github.com/libdns/oraclecloud` |
| 10 | + |
| 11 | +## Build & Test Commands |
| 12 | + |
| 13 | +```bash |
| 14 | +go build ./... # Build |
| 15 | +go test ./... # Run all tests |
| 16 | +go test -run TestName # Run a single test |
| 17 | +go mod tidy # Tidy module graph (CI will fail if this produces changes) |
| 18 | +``` |
| 19 | + |
| 20 | +## Architecture |
| 21 | + |
| 22 | +All code lives in two source files: |
| 23 | + |
| 24 | +- **`provider.go`** — the entire implementation: `Provider` struct, all five libdns interface methods, OCI client initialisation, authentication strategies, zone resolution, record conversion, and helper functions. |
| 25 | +- **`provider_test.go`** + **`test_helpers_test.go`** — unit tests using a `fakeDNSClient` that implements the `dnsAPI` interface in-memory; no live OCI calls needed. |
| 26 | + |
| 27 | +### Key Design Patterns |
| 28 | + |
| 29 | +- **`dnsAPI` interface** (bottom of `provider.go`) — abstracts the OCI DNS SDK client behind five methods (`GetZone`, `GetZoneRecords`, `PatchZoneRecords`, `UpdateRRSet`, `ListZones`). The real client is `sdkDNSClient`; tests inject `fakeDNSClient`. |
| 30 | +- **Authentication cascade** — `configurationProvider()` resolves auth via: explicit API-key fields → OCI config file → OCI CLI environment variables → instance principal. The `Auth` field (`auto`, `api_key`, `config_file`, `environment`) controls which path is used. |
| 31 | +- **Zone resolution** — `resolveZone()` accepts either a zone name or an OCID, calls `GetZone` to normalise it, and returns a `zoneRef` (canonical name + API reference). |
| 32 | +- **Scope/ViewID propagation** — every OCI API request passes through an `apply*Options` helper that sets scope (`GLOBAL`/`PRIVATE`) and optional `ViewID`. |
| 33 | +- **Record conversion** — `toLibdnsRecord()` converts OCI `Record` → typed libdns records (e.g. `libdns.Address`, `libdns.CNAME`); `recordToDetails()`/`recordToOperation()` convert the other direction using `libdns.RR.RR()` for serialisation. |
| 34 | +- **`SetRecords` is per-RRSet** — records are grouped by `(domain, rtype)` via `groupRecordsByRRSet()`, then each group is atomically replaced with `UpdateRRSet`. |
| 35 | + |
| 36 | +## CI |
| 37 | + |
| 38 | +GitHub Actions runs `go mod tidy` (must be clean), `go build ./...`, and `go test ./...` on Go 1.24 + stable. Releases are automated via `release-please` with conventional commits. |
| 39 | + |
| 40 | +## Conventions |
| 41 | + |
| 42 | +- Use conventional commits (`feat:`, `fix:`, `chore:`, etc.) — release-please generates releases from these. |
| 43 | +- OCI CLI environment variable names are defined as constants (`envCLI*`) at the top of `provider.go`. |
| 44 | +- Zone names are always normalised to trailing-dot form internally via `normalizeZoneName()`. |
| 45 | +- libdns record names use relative form (`@` for apex, `www` for subdomains); OCI uses absolute FQDNs — conversion happens in `absoluteDomainForAPI()` and `toLibdnsRecord()`. |
0 commit comments