diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..818a46e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,45 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +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`. + +Module path: `github.com/libdns/oraclecloud` + +## Build & Test Commands + +```bash +go build ./... # Build +go test ./... # Run all tests +go test -run TestName # Run a single test +go mod tidy # Tidy module graph (CI will fail if this produces changes) +``` + +## Architecture + +All code lives in two source files: + +- **`provider.go`** — the entire implementation: `Provider` struct, all five libdns interface methods, OCI client initialisation, authentication strategies, zone resolution, record conversion, and helper functions. +- **`provider_test.go`** + **`test_helpers_test.go`** — unit tests using a `fakeDNSClient` that implements the `dnsAPI` interface in-memory; no live OCI calls needed. + +### Key Design Patterns + +- **`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`. +- **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. +- **Zone resolution** — `resolveZone()` accepts either a zone name or an OCID, calls `GetZone` to normalise it, and returns a `zoneRef` (canonical name + API reference). +- **Scope/ViewID propagation** — every OCI API request passes through an `apply*Options` helper that sets scope (`GLOBAL`/`PRIVATE`) and optional `ViewID`. +- **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. +- **`SetRecords` is per-RRSet** — records are grouped by `(domain, rtype)` via `groupRecordsByRRSet()`, then each group is atomically replaced with `UpdateRRSet`. + +## CI + +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. + +## Conventions + +- Use conventional commits (`feat:`, `fix:`, `chore:`, etc.) — release-please generates releases from these. +- OCI CLI environment variable names are defined as constants (`envCLI*`) at the top of `provider.go`. +- Zone names are always normalised to trailing-dot form internally via `normalizeZoneName()`. +- libdns record names use relative form (`@` for apex, `www` for subdomains); OCI uses absolute FQDNs — conversion happens in `absoluteDomainForAPI()` and `toLibdnsRecord()`. diff --git a/README.md b/README.md index eb788bd..2c91735 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ For Go modules, that means: - `feat:` conventional commits map to minor releases - `feat!:` or any commit with a `BREAKING CHANGE:` footer maps to a major release - if this module ever releases `v2+`, the Go module path must also change to include the major suffix - such as `github.com/Djelibeybi/libdns-oraclecloud/v2` + such as `github.com/libdns/oraclecloud/v2` GitHub Actions uses `release-please` to turn conventional commits merged to `main` into release PRs, SemVer tags, changelog updates, and GitHub Releases. @@ -126,4 +126,4 @@ SemVer tags, changelog updates, and GitHub Releases. force use of `~/.oci/config`, set `Auth: "config_file"`. - For private zones accessed by name, OCI requires `ViewID`. - `SetRecords` is atomic per RRSet because OCI exposes RRSet replacement as a single operation, but it is not atomic across multiple distinct RRSets. -- The module path is `github.com/Djelibeybi/libdns-oraclecloud`. +- The module path is `github.com/libdns/oraclecloud`. diff --git a/cmd/ocismoke/main.go b/cmd/ocismoke/main.go index 684ba0a..8879db7 100644 --- a/cmd/ocismoke/main.go +++ b/cmd/ocismoke/main.go @@ -11,8 +11,8 @@ import ( "strings" "time" - oraclecloud "github.com/Djelibeybi/libdns-oraclecloud" - "github.com/Djelibeybi/libdns-oraclecloud/internal/txtrdata" + oraclecloud "github.com/libdns/oraclecloud" + "github.com/libdns/oraclecloud/internal/txtrdata" "github.com/libdns/libdns" ) diff --git a/go.mod b/go.mod index fd0e891..dc5e859 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/Djelibeybi/libdns-oraclecloud +module github.com/libdns/oraclecloud go 1.25.0 diff --git a/provider.go b/provider.go index ddaa892..64e4eaf 100644 --- a/provider.go +++ b/provider.go @@ -12,7 +12,7 @@ import ( "sync" "time" - "github.com/Djelibeybi/libdns-oraclecloud/internal/txtrdata" + "github.com/libdns/oraclecloud/internal/txtrdata" "github.com/libdns/libdns" "github.com/oracle/oci-go-sdk/v65/common" ociauth "github.com/oracle/oci-go-sdk/v65/common/auth"