Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ This package only supports **API Key authentication**. Refer to the [Gandi's Pub

Start by [retrieving your API key](https://account.gandi.net/) from the _Security_ section in Gandi account admin panel to be able to make authenticated requests to the API.

### Cross-organization access

If the PAT user's default organization is not the one that owns the domain you want to manage, list endpoints (`/v5/domain/domains`, `/v5/livedns/domains`) will still find the domain because Gandi filters by all visible orgs, but per-record-set endpoints will return `404`. Setting `Provider.SharingId` to the UUID of the org that owns the domain causes the provider to send `X-Gandi-Sharing-Id: <uuid>` on every request, and the per-record-set endpoints then succeed.

Note: the documented form of this hint is the [`sharing_id` query string parameter](https://api.gandi.net/docs/reference/#Sharing-ID), but in practice that form doesn't reach per-record-set endpoints. The `X-Gandi-Sharing-Id` header is empirically required there but isn't currently part of the public reference.

## Technical limitations

The [LiveDNS documentation](https://api.gandi.net/docs/livedns/) states that records with the same name and type are merged so that their `rrset_values` are grouped together.
Expand Down
3 changes: 3 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ func (p *Provider) getDomain(ctx context.Context, zone string) (gandiDomain, err
func (p *Provider) doRequest(req *http.Request, result interface{}) (gandiStatus, error) {
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", p.BearerToken))
req.Header.Set("Accept", "application/json")
if p.SharingId != "" {
req.Header.Set("X-Gandi-Sharing-Id", p.SharingId)
}

resp, err := http.DefaultClient.Do(req)

Expand Down
1 change: 1 addition & 0 deletions provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
// Provider implements the libdns interfaces for Gandi.
type Provider struct {
BearerToken string `json:"bearer_token,omitempty"`
SharingId string `json:"sharing_id,omitempty"`

domains map[string]gandiDomain
mutex sync.Mutex
Expand Down