ae6a4d7f4c
Task 9 Фазы 1B: узкий интерфейс TenantStore (внутри store.Account/Template/Domain,
без db.* в api) реализован тонкими обёртками в internal/store/tenant.go; API.Store/
Cipher/Reg добавлены к существующему Svc. Роуты POST/GET/DELETE для accounts/
templates/domains + POST /accounts/{aid}/import (ListZones -> CreateDomain на зону).
accountResponse не содержит секрет ни в каком виде.
98 lines
3.4 KiB
Go
98 lines
3.4 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/go-chi/chi/v5/middleware"
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/vasyakrg/dns-autoresolver/internal/diff"
|
|
"github.com/vasyakrg/dns-autoresolver/internal/provider"
|
|
"github.com/vasyakrg/dns-autoresolver/internal/service"
|
|
"github.com/vasyakrg/dns-autoresolver/internal/store"
|
|
"github.com/vasyakrg/dns-autoresolver/internal/store/dto"
|
|
)
|
|
|
|
// CheckApplier is the service surface the API depends on.
|
|
type CheckApplier interface {
|
|
Check(ctx context.Context, domainID uuid.UUID) (diff.Changeset, error)
|
|
Apply(ctx context.Context, domainID uuid.UUID, req service.ApplyRequest) (diff.Changeset, error)
|
|
}
|
|
|
|
// TenantStore is the narrow persistence surface the CRUD handlers depend on.
|
|
// *store.Store satisfies it directly via its thin wrapper methods (see
|
|
// internal/store/tenant.go); tests can supply their own mock.
|
|
type TenantStore interface {
|
|
CreateAccount(ctx context.Context, projectID uuid.UUID, provider, secretEnc, comment string) (store.Account, error)
|
|
ListAccounts(ctx context.Context, projectID uuid.UUID) ([]store.Account, error)
|
|
GetAccount(ctx context.Context, id, projectID uuid.UUID) (store.Account, error)
|
|
DeleteAccount(ctx context.Context, id, projectID uuid.UUID) error
|
|
|
|
CreateTemplate(ctx context.Context, projectID uuid.UUID, name string, doc dto.TemplateDoc) (store.Template, error)
|
|
ListTemplates(ctx context.Context, projectID uuid.UUID) ([]store.Template, error)
|
|
UpdateTemplate(ctx context.Context, id, projectID uuid.UUID, name string, doc dto.TemplateDoc) (store.Template, error)
|
|
DeleteTemplate(ctx context.Context, id, projectID uuid.UUID) error
|
|
|
|
CreateDomain(ctx context.Context, projectID, accountID uuid.UUID, zoneName, zoneID string, templateID *uuid.UUID) (store.Domain, error)
|
|
ListDomains(ctx context.Context, projectID uuid.UUID) ([]store.Domain, error)
|
|
DeleteDomain(ctx context.Context, id, projectID uuid.UUID) error
|
|
}
|
|
|
|
// Cipher encrypts/decrypts provider account secrets. *crypto.Cipher satisfies it.
|
|
type Cipher interface {
|
|
Encrypt(plaintext []byte) (string, error)
|
|
Decrypt(enc string) ([]byte, error)
|
|
}
|
|
|
|
// ProviderRegistry resolves a provider.Provider by name. *registry.Registry satisfies it.
|
|
type ProviderRegistry interface {
|
|
ByName(name string) (provider.Provider, error)
|
|
}
|
|
|
|
// API holds handler dependencies.
|
|
type API struct {
|
|
Svc CheckApplier
|
|
Store TenantStore
|
|
Cipher Cipher
|
|
Reg ProviderRegistry
|
|
}
|
|
|
|
func NewRouter(a *API) http.Handler {
|
|
r := chi.NewRouter()
|
|
r.Use(middleware.RequestID)
|
|
r.Use(middleware.Recoverer)
|
|
|
|
r.Route("/api/v1/projects/{pid}", func(r chi.Router) {
|
|
r.Route("/domains", func(r chi.Router) {
|
|
r.Post("/", a.handleCreateDomain)
|
|
r.Get("/", a.handleListDomains)
|
|
r.Route("/{did}", func(r chi.Router) {
|
|
r.Get("/check", a.handleCheck)
|
|
r.Post("/apply", a.handleApply)
|
|
r.Delete("/", a.handleDeleteDomain)
|
|
})
|
|
})
|
|
|
|
r.Route("/accounts", func(r chi.Router) {
|
|
r.Post("/", a.handleCreateAccount)
|
|
r.Get("/", a.handleListAccounts)
|
|
r.Route("/{aid}", func(r chi.Router) {
|
|
r.Delete("/", a.handleDeleteAccount)
|
|
r.Post("/import", a.handleImportZones)
|
|
})
|
|
})
|
|
|
|
r.Route("/templates", func(r chi.Router) {
|
|
r.Post("/", a.handleCreateTemplate)
|
|
r.Get("/", a.handleListTemplates)
|
|
r.Route("/{tid}", func(r chi.Router) {
|
|
r.Put("/", a.handleUpdateTemplate)
|
|
r.Delete("/", a.handleDeleteTemplate)
|
|
})
|
|
})
|
|
})
|
|
return r
|
|
}
|