mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-19 16:56:39 +00:00
connect api to store and manager for domains
This commit is contained in:
124
management/internals/modules/reverseproxy/domain/manager.go
Normal file
124
management/internals/modules/reverseproxy/domain/manager.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/types"
|
||||
)
|
||||
|
||||
type domainType string
|
||||
|
||||
const (
|
||||
TypeFree domainType = "free"
|
||||
TypeCustom domainType = "custom"
|
||||
)
|
||||
|
||||
type Domain struct {
|
||||
ID string `gorm:"unique;primaryKey;autoIncrement"`
|
||||
Domain string `gorm:"unique"` // Domain records must be unique, this avoids domain reuse across accounts.
|
||||
AccountID string `gorm:"index"`
|
||||
Type domainType `gorm:"-"`
|
||||
Validated bool
|
||||
}
|
||||
|
||||
type store interface {
|
||||
GetAccount(ctx context.Context, accountID string) (*types.Account, error)
|
||||
|
||||
GetCustomDomain(ctx context.Context, accountID string, domainID string) (*Domain, error)
|
||||
ListFreeDomains(ctx context.Context, accountID string) ([]string, error)
|
||||
ListCustomDomains(ctx context.Context, accountID string) ([]*Domain, error)
|
||||
CreateCustomDomain(ctx context.Context, accountID string, domainName string, validated bool) (*Domain, error)
|
||||
UpdateCustomDomain(ctx context.Context, accountID string, d *Domain) (*Domain, error)
|
||||
DeleteCustomDomain(ctx context.Context, accountID string, domainID string) error
|
||||
}
|
||||
|
||||
type Manager struct {
|
||||
store store
|
||||
validator Validator
|
||||
}
|
||||
|
||||
func NewManager(store store) Manager {
|
||||
return Manager{
|
||||
store: store,
|
||||
validator: Validator{
|
||||
resolver: net.DefaultResolver,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (m Manager) GetDomains(ctx context.Context, accountID string) ([]*Domain, error) {
|
||||
account, err := m.store.GetAccount(ctx, accountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get account: %w", err)
|
||||
}
|
||||
free, err := m.store.ListFreeDomains(ctx, accountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list free domains: %w", err)
|
||||
}
|
||||
domains, err := m.store.ListCustomDomains(ctx, accountID)
|
||||
if err != nil {
|
||||
// TODO: check for "no records" type error. Because that is a success condition.
|
||||
return nil, fmt.Errorf("list custom domains: %w", err)
|
||||
}
|
||||
|
||||
// Prepend each free domain with the account nonce and then add it to the domain
|
||||
// array to be returned.
|
||||
// This account nonce is added to free domains to prevent users being able to
|
||||
// query free domain usage across accounts and simplifies tracking free domain
|
||||
// usage across accounts.
|
||||
for _, name := range free {
|
||||
domains = append(domains, &Domain{
|
||||
Domain: account.ReverseProxyFreeDomainNonce + "." + name,
|
||||
AccountID: accountID,
|
||||
Type: TypeFree,
|
||||
Validated: true,
|
||||
})
|
||||
}
|
||||
return domains, nil
|
||||
}
|
||||
|
||||
func (m Manager) CreateDomain(ctx context.Context, accountID, domainName string) (*Domain, error) {
|
||||
// Attempt an initial validation; however, a failure is still acceptable for creation
|
||||
// because the user may not yet have configured their DNS records, or the DNS update
|
||||
// has not yet reached the servers that are queried by the validation resolver.
|
||||
var validated bool
|
||||
// TODO: retrieve in use reverse proxy addresses from somewhere!
|
||||
var reverseProxyAddresses []string
|
||||
if m.validator.IsValid(ctx, domainName, reverseProxyAddresses) {
|
||||
validated = true
|
||||
}
|
||||
|
||||
d, err := m.store.CreateCustomDomain(ctx, accountID, domainName, validated)
|
||||
if err != nil {
|
||||
return d, fmt.Errorf("create domain in store: %w", err)
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
func (m Manager) DeleteDomain(ctx context.Context, accountID, domainID string) error {
|
||||
if err := m.store.DeleteCustomDomain(ctx, accountID, domainID); err != nil {
|
||||
// TODO: check for "no records" type error. Because that is a success condition.
|
||||
return fmt.Errorf("delete domain from store: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m Manager) ValidateDomain(accountID, domainID string) {
|
||||
d, err := m.store.GetCustomDomain(context.Background(), accountID, domainID)
|
||||
if err != nil {
|
||||
// TODO: something? Log?
|
||||
return
|
||||
}
|
||||
// TODO: retrieve in use reverse proxy addresses from somewhere!
|
||||
var reverseProxyAddresses []string
|
||||
if m.validator.IsValid(context.Background(), d.Domain, reverseProxyAddresses) {
|
||||
d.Validated = true
|
||||
if _, err := m.store.UpdateCustomDomain(context.Background(), accountID, d); err != nil {
|
||||
// TODO: something? Log?
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user