Documentation
¶
Overview ¶
Package membership implements the registry's network membership handlers: create, delete, rename, join, leave, invite, kick, promote, demote, transfer-ownership, role query, member-tags, task-exec, and list-networks. It is extracted from pkg/registry/server as part of the R4.1 registry decomposition.
Thread safety: all exported Handler* methods are safe for concurrent use. Locking is delegated to the server through mu (shared with Server) and callback functions that acquire whatever locks are needed internally.
Index ¶
- Constants
- func ValidateNetworkName(name string) error
- type Callbacks
- type NetworkInfo
- type NetworkInvite
- type NetworkPolicy
- type Role
- type Store
- func (st *Store) HandleCreateNetwork(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) HandleDeleteNetwork(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) HandleDemoteMember(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) HandleGetMemberRole(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) HandleGetMemberTags(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) HandleInviteToNetwork(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) HandleJoinNetwork(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) HandleKickMember(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) HandleLeaveNetwork(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) HandleListNetworks(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) HandlePollInvites(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) HandlePromoteMember(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) HandleRenameNetwork(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) HandleRespondInvite(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) HandleSetMemberTags(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) HandleSetNetworkEnterprise(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) HandleTransferOwnership(msg map[string]interface{}) (map[string]interface{}, error)
- func (st *Store) ReplaceState(networks map[uint16]*NetworkInfo, inviteInbox map[uint32][]*NetworkInvite)
Constants ¶
const ( // MaxInviteInbox limits the number of pending invites per node. MaxInviteInbox = 100 // InviteTTL is the maximum age of a pending invite. InviteTTL = 30 * 24 * time.Hour )
Variables ¶
This section is empty.
Functions ¶
func ValidateNetworkName ¶
ValidateNetworkName checks that a network name is valid.
Types ¶
type Callbacks ¶
type Callbacks struct {
// Save triggers a debounced snapshot write.
Save func()
// Audit records an audit log entry.
Audit func(action string, attrs ...any)
// RecordWALNetworkCreate records a network-create WAL entry.
RecordWALNetworkCreate func(netID uint16, name, joinRule, token, adminToken string, enterprise bool, creatorNodeID uint32, createdAt string)
// RecordWALNetworkJoin records a network-join WAL entry.
RecordWALNetworkJoin func(nodeID uint32, netID uint16)
// RecordWALNetworkLeave records a network-leave WAL entry.
RecordWALNetworkLeave func(nodeID uint32, netID uint16)
// RecordWALNetworkDelete records a network-delete WAL entry.
RecordWALNetworkDelete func(netID uint16)
// InvalidateListNodesCache drops the per-network list_nodes cache.
InvalidateListNodesCache func(netID uint16)
// PublishMembershipChanged publishes a membership.changed bus event.
PublishMembershipChanged func(netID uint16)
// ApplyRBACPreAssignment checks and applies any pre-assigned roles.
// Caller must hold the global write lock.
ApplyRBACPreAssignment func(netID uint16, nodeID uint32)
// RequireAdminToken validates the admin_token field in a message.
RequireAdminToken func(msg map[string]interface{}) error
// RequireNetworkRole checks RBAC role for network operations.
RequireNetworkRole func(msg map[string]interface{}, netID uint16, roles ...Role) error
// RequireEnterprise checks that the given network has the Enterprise flag.
RequireEnterprise func(netID uint16) error
// VerifyNodeSignature verifies an Ed25519 signature for a node write.
// Takes pubKey and adminToken (already copied under RLock by caller).
VerifyNodeSignature func(pubKey []byte, adminToken string, msg map[string]interface{}, challenge string) error
// AdminToken returns the current admin token (caller must not hold write lock).
AdminToken func() string
// NodeExists returns true if nodeID is registered. Caller must hold mu.RLock
// or mu.Lock before calling.
NodeExists func(nodeID uint32) bool
// GetNodeForRead returns node fields needed before write lock.
// Returns (pubKey, ok). Caller must hold mu.RLock.
GetNodePubKey func(nodeID uint32) (pubKey []byte, ok bool)
// GetNode returns a node's key fields. Caller must hold mu (read or write).
GetNode func(nodeID uint32) (pubKey []byte, networks []uint16, externalID string, ok bool)
// NodeNetworks returns a copy of node.Networks. Caller must hold mu.
NodeNetworks func(nodeID uint32) ([]uint16, bool)
// AppendNodeNetwork appends netID to the node's Networks slice under its shard lock.
// Caller must hold mu.Lock.
AppendNodeNetwork func(nodeID uint32, netID uint16)
// RemoveNodeNetwork removes netID from the node's Networks slice under its shard lock.
// Caller must hold mu.Lock. Returns false if the node was not in the network.
RemoveNodeNetwork func(nodeID uint32, netID uint16) bool
// IncInvitesSent increments the invites_sent_total counter.
IncInvitesSent func()
// IncInvitesAccepted increments the invites_accepted_total counter.
IncInvitesAccepted func()
// IncInvitesRejected increments the invites_rejected_total counter.
IncInvitesRejected func()
// IncRbacOps increments the rbac_operations_total{op=label} counter.
IncRbacOps func(op string)
}
Callbacks bundles the side-effect functions the Store calls on state changes. All functions must be safe for concurrent use.
type NetworkInfo ¶
type NetworkInfo struct {
ID uint16
Name string
JoinRule string
Token string // for token-gated networks
Members []uint32
MemberRoles map[uint32]Role // per-member RBAC roles
MemberTags map[uint32][]string // admin-assigned per-member tags (e.g. "service")
AdminToken string // per-network admin token (optional)
Policy NetworkPolicy // network policy (membership limits, port restrictions)
Rules *wire.NetworkRules // managed network rules (nil = normal network)
ExprPolicy json.RawMessage // programmable policy engine document (nil = none)
Enterprise bool // enterprise network (gates Phase 2-5 features)
Created time.Time
RequestCount atomic.Int64 // per-network request counter (dashboard stats)
}
NetworkInfo holds the in-memory state for a single network.
type NetworkInvite ¶
type NetworkInvite struct {
NetworkID uint16 `json:"network_id"`
InviterID uint32 `json:"inviter_id"`
Timestamp time.Time `json:"timestamp"`
}
NetworkInvite is a pending network invitation stored in the invite inbox.
type NetworkPolicy ¶
type NetworkPolicy struct {
MaxMembers int `json:"max_members"`
AllowedPorts []uint16 `json:"allowed_ports"`
Description string `json:"description"`
}
NetworkPolicy defines constraints and metadata for a network.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store holds membership handler logic. The actual data maps (networks, inviteInbox, nextNet) are owned by the parent server and shared via the mu pointer. This is intentional for the R4.1 phase — locking semantics are preserved by using the same mutex as the server.
func NewStore ¶
func NewStore( mu *sync.RWMutex, networks map[uint16]*NetworkInfo, inviteInbox map[uint32][]*NetworkInvite, nextNet *uint16, cb Callbacks, now func() time.Time, ) *Store
NewStore creates a ready-to-use membership Store. All pointer parameters are shared with the parent server and must not be nil.
func (*Store) HandleCreateNetwork ¶
HandleCreateNetwork implements the "create_network" protocol command.
func (*Store) HandleDeleteNetwork ¶
HandleDeleteNetwork implements the "delete_network" protocol command.
func (*Store) HandleDemoteMember ¶
HandleDemoteMember implements the "demote_member" protocol command.
func (*Store) HandleGetMemberRole ¶
HandleGetMemberRole implements the "get_member_role" protocol command.
func (*Store) HandleGetMemberTags ¶
HandleGetMemberTags implements the "get_member_tags" protocol command.
func (*Store) HandleInviteToNetwork ¶
HandleInviteToNetwork implements the "invite_to_network" protocol command.
func (*Store) HandleJoinNetwork ¶
HandleJoinNetwork implements the "join_network" protocol command.
func (*Store) HandleKickMember ¶
HandleKickMember implements the "kick_member" protocol command.
func (*Store) HandleLeaveNetwork ¶
HandleLeaveNetwork implements the "leave_network" protocol command.
func (*Store) HandleListNetworks ¶
HandleListNetworks implements the "list_networks" protocol command.
func (*Store) HandlePollInvites ¶
HandlePollInvites implements the "poll_invites" protocol command.
func (*Store) HandlePromoteMember ¶
HandlePromoteMember implements the "promote_member" protocol command.
func (*Store) HandleRenameNetwork ¶
HandleRenameNetwork implements the "rename_network" protocol command.
func (*Store) HandleRespondInvite ¶
HandleRespondInvite implements the "respond_invite" protocol command.
func (*Store) HandleSetMemberTags ¶
HandleSetMemberTags implements the "set_member_tags" protocol command.
func (*Store) HandleSetNetworkEnterprise ¶
func (st *Store) HandleSetNetworkEnterprise(msg map[string]interface{}) (map[string]interface{}, error)
HandleSetNetworkEnterprise implements the "set_network_enterprise" command.
func (*Store) HandleTransferOwnership ¶
func (st *Store) HandleTransferOwnership(msg map[string]interface{}) (map[string]interface{}, error)
HandleTransferOwnership implements the "transfer_ownership" protocol command.
func (*Store) ReplaceState ¶
func (st *Store) ReplaceState(networks map[uint16]*NetworkInfo, inviteInbox map[uint32][]*NetworkInvite)
ReplaceState atomically swaps the membership store's network and invite maps with replacement values. Called by the server after applying a replication snapshot so the store's internal map pointers stay current. Must be called with s.mu held (Lock).