acme-dns: allow the HTTP storage server to create the CNAME (#2437)

This commit is contained in:
Ludovic Fernandez 2025-02-16 16:12:47 +01:00 committed by GitHub
commit b16da88eb7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 37 additions and 2 deletions

View file

@ -178,16 +178,26 @@ func (d *DNSProvider) register(ctx context.Context, domain, fqdn string) error {
return err
}
var cnameCreated bool
// Store the new account in the storage and call save to persist the data.
err = d.storage.Put(ctx, domain, newAcct)
if err != nil {
return err
cnameCreated = errors.Is(err, internal.ErrCNAMEAlreadyCreated)
if !cnameCreated {
return err
}
}
err = d.storage.Save(ctx)
if err != nil {
return err
}
if cnameCreated {
return nil
}
// Stop issuance by returning an error.
// The user needs to perform a manual one-time CNAME setup in their DNS zone
// to complete the setup of the new account we created.

View file

@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
@ -17,6 +18,8 @@ import (
var _ goacmedns.Storage = (*HTTPStorage)(nil)
var ErrCNAMEAlreadyCreated = errors.New("the CNAME has already been created")
// HTTPStorage is an implementation of [acmedns.Storage] over HTTP.
type HTTPStorage struct {
client *http.Client
@ -98,6 +101,11 @@ func (s *HTTPStorage) do(req *http.Request, result any) error {
}
if result == nil {
// Hack related to `Put`.
if resp.StatusCode == http.StatusCreated {
return ErrCNAMEAlreadyCreated
}
return nil
}

View file

@ -137,3 +137,18 @@ func TestHTTPStorage_Put_error(t *testing.T) {
err := storage.Put(context.Background(), "example.com", account)
require.Error(t, err)
}
func TestHTTPStorage_Put_CNAME_created(t *testing.T) {
storage := setupTest(t, "POST /example.com", "", http.StatusCreated)
account := goacmedns.Account{
FullDomain: "foo.example.com",
SubDomain: "foo",
Username: "user",
Password: "secret",
ServerURL: "https://example.com",
}
err := storage.Put(context.Background(), "example.com", account)
require.ErrorIs(t, err, ErrCNAMEAlreadyCreated)
}

View file

@ -61,7 +61,9 @@ Endpoint: `POST <BaseURL>/<domain>`
### Response
Response status code 200.
Response status code:
- 200: the process will be stopped to allow the user to create the CNAME.
- 201: the process will continue without error (the CNAME should be created by the server)
No expected body.