Documentation
¶
Overview ¶
Package multisite resolves an authorized exact authority to a stable site ID. Products own ingress trust, authentication, site bindings and domain isolation.
Index ¶
Examples ¶
Constants ¶
const Resolve = "achrix.multisite.resolve"
Variables ¶
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct{ Sites []Site }
Config is trusted, finite product composition input. New copies its inventory; replacing configuration requires a new validated Module/Application composition. No arbitrary site-count limit is imposed; products own inventory/resource budgets.
type Module ¶
type Module struct {
// contains filtered or unexported fields
}
Module owns immutable bindings and one-shot lifecycle state. It acquires no storage/network resources and starts no workers. Do not share a Module between Applications; products explicitly wire its Service to its owning Application.
func New ¶
New validates the complete inventory before any runtime effect. Every site requires at least one authority; duplicate IDs or authorities (even repeated aliases for one site) are rejected. Validation and copying are linear in input.
func (*Module) Descriptor ¶
func (m *Module) Descriptor() achrix.Descriptor
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service traverses Core authorization and the owning Module lifecycle. app must be the Application composing module; typed collaborators are explicitly product-wired, as with other Foundation Services, never discovered from metadata.
func NewService ¶
func NewService(app *achrix.Application, module *Module) (*Service, error)
func (*Service) Resolve ¶
func (s *Service) Resolve(parent context.Context, actor achrix.Principal, authority string) (SiteID, error)
Resolve validates syntax without revealing binding existence, then authorizes the exact authority before lookup. A derived maximum one-second context retains any earlier caller deadline/cancellation. Policies are trusted synchronous code and must honor cancellation; this API cannot forcibly interrupt callbacks. Unknown and disabled bindings share ErrNotFound. The result is only a site ID: TLS/Host/proxy trust, resource access and site-to-Application/store bindings are separate product responsibilities. No normalization, suffix/default-port fallback or discovery occurs. Lookup is constant time in configured inventory size.
Example ¶
package main
import (
"context"
"fmt"
"time"
"github.com/AChWorks/achrix"
"github.com/AChWorks/achrix/multisite"
)
func main() {
resolver, err := multisite.New(multisite.Config{Sites: []multisite.Site{
{ID: "site-a", Authorities: []string{"a.example", "a.example:443"}},
{ID: "site-b", Authorities: []string{"b.example"}},
}})
if err != nil {
panic(err)
}
// This example's product policy grants only authority resolution. Actual
// authentication, trusted ingress and site resource authorization are separate.
policy := achrix.PolicyFunc(func(_ context.Context, actor achrix.Principal, capability, authority string) error {
if actor == "product-router" && capability == multisite.Resolve && authority == "a.example" {
return nil
}
return achrix.ErrDenied
})
app, err := achrix.New(achrix.Config{StartupTimeout: time.Second, ShutdownTimeout: time.Second}, policy, resolver)
if err != nil {
panic(err)
}
service, err := multisite.NewService(app, resolver)
if err != nil {
panic(err)
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
if err = app.Start(ctx); err != nil {
panic(err)
}
id, err := service.Resolve(ctx, "product-router", "a.example")
if err != nil {
panic(err)
}
fmt.Println(id)
cleanup, cleanupCancel := context.WithTimeout(context.Background(), time.Second)
defer cleanupCancel()
if err = app.Shutdown(cleanup); err != nil {
panic(err)
}
}
Output: site-a