mirror of
https://github.com/jsiebens/ionscale.git
synced 2026-03-31 15:07:49 +01:00
temp: additional events
This commit is contained in:
+94
-29
@@ -7,20 +7,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
tailnetCreated = "ionscale.tailnet.created"
|
tailnetCreated = "ionscale.tailnet.create"
|
||||||
tailnetDeleted = "ionscale.tailnet.deleted"
|
tailnetIamUpdated = "ionscale.tailnet.iam.update"
|
||||||
nodeCreated = "ionscale.node.created"
|
tailnetAclUpdated = "ionscale.tailnet.acl.update"
|
||||||
|
tailnetDNSConfigUpdated = "ionscale.tailnet.dns_config.update"
|
||||||
|
nodeCreated = "ionscale.node.create"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TailnetCreated(tailnet *domain.Tailnet, actor *domain.User) cloudevents.Event {
|
func TailnetCreated(tailnet *domain.Tailnet, actor ActorOpts) cloudevents.Event {
|
||||||
data := &EventData{
|
data := &EventData[any]{
|
||||||
Tailnet: &Target{ID: idToStr(tailnet.ID), Name: tailnet.Name},
|
Tailnet: &Target{ID: idToStr(tailnet.ID), Name: tailnet.Name},
|
||||||
Target: &Target{ID: idToStr(tailnet.ID), Name: tailnet.Name},
|
Target: &Target{ID: idToStr(tailnet.ID), Name: tailnet.Name},
|
||||||
Actor: system,
|
Actor: actor(),
|
||||||
}
|
|
||||||
|
|
||||||
if actor != nil {
|
|
||||||
data.Actor = Actor{ID: idToStr(actor.ID), Name: actor.Name}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
event := cloudevents.NewEvent()
|
event := cloudevents.NewEvent()
|
||||||
@@ -30,11 +28,65 @@ func TailnetCreated(tailnet *domain.Tailnet, actor *domain.User) cloudevents.Eve
|
|||||||
return event
|
return event
|
||||||
}
|
}
|
||||||
|
|
||||||
func MachineCreated(machine *domain.Machine, actor *domain.User) cloudevents.Event {
|
func TailnetIAMUpdated(tailnet *domain.Tailnet, old *domain.IAMPolicy, actor ActorOpts) cloudevents.Event {
|
||||||
data := &EventData{
|
data := &EventData[*domain.IAMPolicy]{
|
||||||
|
Tailnet: &Target{ID: idToStr(tailnet.ID), Name: tailnet.Name},
|
||||||
|
Target: &Target{ID: idToStr(tailnet.ID), Name: tailnet.Name},
|
||||||
|
Actor: actor(),
|
||||||
|
Attr: &Attr[*domain.IAMPolicy]{
|
||||||
|
New: &tailnet.IAMPolicy,
|
||||||
|
Old: old,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
event := cloudevents.NewEvent()
|
||||||
|
event.SetType(tailnetIamUpdated)
|
||||||
|
_ = event.SetData(cloudevents.ApplicationJSON, data)
|
||||||
|
|
||||||
|
return event
|
||||||
|
}
|
||||||
|
|
||||||
|
func TailnetACLUpdated(tailnet *domain.Tailnet, old *domain.ACLPolicy, actor ActorOpts) cloudevents.Event {
|
||||||
|
data := &EventData[*domain.ACLPolicy]{
|
||||||
|
Tailnet: &Target{ID: idToStr(tailnet.ID), Name: tailnet.Name},
|
||||||
|
Target: &Target{ID: idToStr(tailnet.ID), Name: tailnet.Name},
|
||||||
|
Actor: actor(),
|
||||||
|
Attr: &Attr[*domain.ACLPolicy]{
|
||||||
|
New: &tailnet.ACLPolicy,
|
||||||
|
Old: old,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
event := cloudevents.NewEvent()
|
||||||
|
event.SetType(tailnetAclUpdated)
|
||||||
|
_ = event.SetData(cloudevents.ApplicationJSON, data)
|
||||||
|
|
||||||
|
return event
|
||||||
|
}
|
||||||
|
|
||||||
|
func TailnetDNSConfigUpdated(tailnet *domain.Tailnet, old *domain.DNSConfig, actor ActorOpts) cloudevents.Event {
|
||||||
|
data := &EventData[*domain.DNSConfig]{
|
||||||
|
Tailnet: &Target{ID: idToStr(tailnet.ID), Name: tailnet.Name},
|
||||||
|
Target: &Target{ID: idToStr(tailnet.ID), Name: tailnet.Name},
|
||||||
|
Actor: actor(),
|
||||||
|
Attr: &Attr[*domain.DNSConfig]{
|
||||||
|
New: &tailnet.DNSConfig,
|
||||||
|
Old: old,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
event := cloudevents.NewEvent()
|
||||||
|
event.SetType(tailnetDNSConfigUpdated)
|
||||||
|
_ = event.SetData(cloudevents.ApplicationJSON, data)
|
||||||
|
|
||||||
|
return event
|
||||||
|
}
|
||||||
|
|
||||||
|
func MachineCreated(machine *domain.Machine, actor ActorOpts) cloudevents.Event {
|
||||||
|
data := &EventData[any]{
|
||||||
Tailnet: &Target{ID: idToStr(machine.Tailnet.ID), Name: machine.Tailnet.Name},
|
Tailnet: &Target{ID: idToStr(machine.Tailnet.ID), Name: machine.Tailnet.Name},
|
||||||
Target: &Target{ID: idToStr(machine.ID), Name: machine.CompleteName(), Addresses: machine.IPs()},
|
Target: &Target{ID: idToStr(machine.ID), Name: machine.CompleteName()},
|
||||||
Actor: UserToActor(actor),
|
Actor: actor(),
|
||||||
}
|
}
|
||||||
|
|
||||||
event := cloudevents.NewEvent()
|
event := cloudevents.NewEvent()
|
||||||
@@ -44,29 +96,39 @@ func MachineCreated(machine *domain.Machine, actor *domain.User) cloudevents.Eve
|
|||||||
return event
|
return event
|
||||||
}
|
}
|
||||||
|
|
||||||
func UserToActor(actor *domain.User) Actor {
|
type ActorOpts func() Actor
|
||||||
if actor == nil {
|
|
||||||
return system
|
func User(u *domain.User) ActorOpts {
|
||||||
|
if u == nil {
|
||||||
|
return SystemAdmin()
|
||||||
}
|
}
|
||||||
|
|
||||||
switch actor.UserType {
|
switch u.UserType {
|
||||||
case domain.UserTypePerson:
|
case domain.UserTypePerson:
|
||||||
return Actor{ID: idToStr(actor.ID), Name: actor.Name}
|
return func() Actor {
|
||||||
|
return Actor{ID: idToStr(u.ID), Name: u.Name}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return system
|
return SystemAdmin()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventData struct {
|
func SystemAdmin() ActorOpts {
|
||||||
Tailnet *Target `json:"tailnet,omitempty"`
|
return func() Actor {
|
||||||
Target *Target `json:"target,omitempty"`
|
return Actor{ID: "", Name: "system admin"}
|
||||||
Actor Actor `json:"actor"`
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventData[T any] struct {
|
||||||
|
Tailnet *Target `json:"tailnet,omitempty"`
|
||||||
|
Target *Target `json:"target,omitempty"`
|
||||||
|
Attr *Attr[T] `json:"attr,omitempty"`
|
||||||
|
Actor Actor `json:"actor"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Target struct {
|
type Target struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Addresses []string `json:"addresses,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Actor struct {
|
type Actor struct {
|
||||||
@@ -74,8 +136,11 @@ type Actor struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Attr[T any] struct {
|
||||||
|
New T `json:"new"`
|
||||||
|
Old T `json:"old,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
func idToStr(id uint64) string {
|
func idToStr(id uint64) string {
|
||||||
return big.NewInt(int64(id)).Text(10)
|
return big.NewInt(int64(id)).Text(10)
|
||||||
}
|
}
|
||||||
|
|
||||||
var system = Actor{ID: "", Name: "ionscale system"}
|
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ func Configure(c *config.Config) error {
|
|||||||
_globalMu.Lock()
|
_globalMu.Lock()
|
||||||
defer _globalMu.Unlock()
|
defer _globalMu.Unlock()
|
||||||
_globalE = &eventer{
|
_globalE = &eventer{
|
||||||
source: c.ServerUrl,
|
source: c.WebPublicUrl.String(),
|
||||||
sinks: sinks,
|
sinks: sinks,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -509,7 +509,7 @@ func (h *AuthenticationHandlers) endMachineRegistrationFlow(c echo.Context, form
|
|||||||
m.IPv4 = domain.IP{Addr: ipv4}
|
m.IPv4 = domain.IP{Addr: ipv4}
|
||||||
m.IPv6 = domain.IP{Addr: ipv6}
|
m.IPv6 = domain.IP{Addr: ipv6}
|
||||||
|
|
||||||
events = append(events, eventlog.MachineCreated(m, user))
|
events = append(events, eventlog.MachineCreated(m, eventlog.User(user)))
|
||||||
} else {
|
} else {
|
||||||
registeredTags := tags
|
registeredTags := tags
|
||||||
advertisedTags := domain.SanitizeTags(req.Hostinfo.RequestTags)
|
advertisedTags := domain.SanitizeTags(req.Hostinfo.RequestTags)
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ func (h *RegistrationHandlers) authenticateMachineWithAuthKey(c echo.Context, ma
|
|||||||
m.IPv4 = domain.IP{Addr: ipv4}
|
m.IPv4 = domain.IP{Addr: ipv4}
|
||||||
m.IPv6 = domain.IP{Addr: ipv6}
|
m.IPv6 = domain.IP{Addr: ipv6}
|
||||||
|
|
||||||
events = append(events, eventlog.MachineCreated(m, &user))
|
events = append(events, eventlog.MachineCreated(m, eventlog.User(&user)))
|
||||||
} else {
|
} else {
|
||||||
sanitizeHostname := dnsname.SanitizeHostname(req.Hostinfo.Hostname)
|
sanitizeHostname := dnsname.SanitizeHostname(req.Hostinfo.Hostname)
|
||||||
if m.Name != sanitizeHostname {
|
if m.Name != sanitizeHostname {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/bufbuild/connect-go"
|
"github.com/bufbuild/connect-go"
|
||||||
"github.com/jsiebens/ionscale/internal/domain"
|
"github.com/jsiebens/ionscale/internal/domain"
|
||||||
|
"github.com/jsiebens/ionscale/internal/eventlog"
|
||||||
"github.com/jsiebens/ionscale/internal/mapping"
|
"github.com/jsiebens/ionscale/internal/mapping"
|
||||||
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
|
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
|
||||||
)
|
)
|
||||||
@@ -60,6 +61,7 @@ func (s *Service) SetACLPolicy(ctx context.Context, req *connect.Request[api.Set
|
|||||||
return nil, logError(err)
|
return nil, logError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eventlog.Send(ctx, eventlog.TailnetACLUpdated(tailnet, &oldPolicy, eventlog.User(principal.User)))
|
||||||
s.sessionManager.NotifyAll(tailnet.ID)
|
s.sessionManager.NotifyAll(tailnet.ID)
|
||||||
|
|
||||||
return connect.NewResponse(&api.SetACLPolicyResponse{}), nil
|
return connect.NewResponse(&api.SetACLPolicyResponse{}), nil
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/bufbuild/connect-go"
|
"github.com/bufbuild/connect-go"
|
||||||
"github.com/jsiebens/ionscale/internal/config"
|
"github.com/jsiebens/ionscale/internal/config"
|
||||||
"github.com/jsiebens/ionscale/internal/domain"
|
"github.com/jsiebens/ionscale/internal/domain"
|
||||||
|
"github.com/jsiebens/ionscale/internal/eventlog"
|
||||||
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
|
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -66,6 +67,7 @@ func (s *Service) SetDNSConfig(ctx context.Context, req *connect.Request[api.Set
|
|||||||
return nil, logError(err)
|
return nil, logError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eventlog.Send(ctx, eventlog.TailnetDNSConfigUpdated(tailnet, &oldConfig, eventlog.User(principal.User)))
|
||||||
s.sessionManager.NotifyAll(tailnet.ID)
|
s.sessionManager.NotifyAll(tailnet.ID)
|
||||||
|
|
||||||
return connect.NewResponse(&api.SetDNSConfigResponse{Config: domainDNSConfigToApiDNSConfig(tailnet)}), nil
|
return connect.NewResponse(&api.SetDNSConfigResponse{Config: domainDNSConfigToApiDNSConfig(tailnet)}), nil
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/bufbuild/connect-go"
|
"github.com/bufbuild/connect-go"
|
||||||
"github.com/jsiebens/ionscale/internal/domain"
|
"github.com/jsiebens/ionscale/internal/domain"
|
||||||
|
"github.com/jsiebens/ionscale/internal/eventlog"
|
||||||
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
|
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -68,6 +69,8 @@ func (s *Service) SetIAMPolicy(ctx context.Context, req *connect.Request[api.Set
|
|||||||
return nil, logError(err)
|
return nil, logError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eventlog.Send(ctx, eventlog.TailnetIAMUpdated(tailnet, &oldPolicy, eventlog.User(principal.User)))
|
||||||
|
|
||||||
return connect.NewResponse(&api.SetIAMPolicyResponse{}), nil
|
return connect.NewResponse(&api.SetIAMPolicyResponse{}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/bufbuild/connect-go"
|
"github.com/bufbuild/connect-go"
|
||||||
|
cloudevents "github.com/cloudevents/sdk-go/v2"
|
||||||
"github.com/jsiebens/ionscale/internal/domain"
|
"github.com/jsiebens/ionscale/internal/domain"
|
||||||
"github.com/jsiebens/ionscale/internal/eventlog"
|
"github.com/jsiebens/ionscale/internal/eventlog"
|
||||||
"github.com/jsiebens/ionscale/internal/mapping"
|
"github.com/jsiebens/ionscale/internal/mapping"
|
||||||
@@ -97,7 +98,12 @@ func (s *Service) CreateTailnet(ctx context.Context, req *connect.Request[api.Cr
|
|||||||
return nil, logError(err)
|
return nil, logError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
eventlog.Send(ctx, eventlog.TailnetCreated(tailnet, principal.User))
|
eventlog.Send(ctx,
|
||||||
|
eventlog.TailnetCreated(tailnet, eventlog.User(principal.User)),
|
||||||
|
eventlog.TailnetIAMUpdated(tailnet, nil, eventlog.User(principal.User)),
|
||||||
|
eventlog.TailnetACLUpdated(tailnet, nil, eventlog.User(principal.User)),
|
||||||
|
eventlog.TailnetDNSConfigUpdated(tailnet, nil, eventlog.User(principal.User)),
|
||||||
|
)
|
||||||
|
|
||||||
resp := &api.CreateTailnetResponse{Tailnet: t}
|
resp := &api.CreateTailnetResponse{Tailnet: t}
|
||||||
|
|
||||||
@@ -119,26 +125,48 @@ func (s *Service) UpdateTailnet(ctx context.Context, req *connect.Request[api.Up
|
|||||||
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
|
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
events := make([]cloudevents.Event, 0)
|
||||||
|
|
||||||
if req.Msg.IamPolicy != nil {
|
if req.Msg.IamPolicy != nil {
|
||||||
if err := validateIamPolicy(req.Msg.IamPolicy); err != nil {
|
if err := validateIamPolicy(req.Msg.IamPolicy); err != nil {
|
||||||
return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid iam policy: %w", err))
|
return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("invalid iam policy: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
tailnet.IAMPolicy = domain.IAMPolicy{}
|
oldPolicy := tailnet.IAMPolicy
|
||||||
if err := mapping.CopyViaJson(req.Msg.IamPolicy, &tailnet.IAMPolicy); err != nil {
|
var newPolicy domain.IAMPolicy
|
||||||
|
|
||||||
|
if err := mapping.CopyViaJson(req.Msg.IamPolicy, &newPolicy); err != nil {
|
||||||
return nil, logError(err)
|
return nil, logError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !oldPolicy.Equal(&newPolicy) {
|
||||||
|
tailnet.IAMPolicy = newPolicy
|
||||||
|
events = append(events, eventlog.TailnetIAMUpdated(tailnet, &oldPolicy, eventlog.User(principal.User)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.Msg.AclPolicy != nil {
|
if req.Msg.AclPolicy != nil {
|
||||||
tailnet.ACLPolicy = domain.ACLPolicy{}
|
oldPolicy := tailnet.ACLPolicy
|
||||||
if err := mapping.CopyViaJson(req.Msg.AclPolicy, &tailnet.ACLPolicy); err != nil {
|
var newPolicy domain.ACLPolicy
|
||||||
|
|
||||||
|
if err := mapping.CopyViaJson(req.Msg.AclPolicy, &newPolicy); err != nil {
|
||||||
return nil, logError(err)
|
return nil, logError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !oldPolicy.Equal(&newPolicy) {
|
||||||
|
tailnet.ACLPolicy = newPolicy
|
||||||
|
events = append(events, eventlog.TailnetACLUpdated(tailnet, &oldPolicy, eventlog.User(principal.User)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.Msg.DnsConfig != nil {
|
if req.Msg.DnsConfig != nil {
|
||||||
tailnet.DNSConfig = apiDNSConfigToDomainDNSConfig(req.Msg.DnsConfig)
|
oldConfig := tailnet.DNSConfig
|
||||||
|
newConfig := apiDNSConfigToDomainDNSConfig(req.Msg.DnsConfig)
|
||||||
|
|
||||||
|
if !oldConfig.Equal(&newConfig) {
|
||||||
|
tailnet.DNSConfig = newConfig
|
||||||
|
events = append(events, eventlog.TailnetDNSConfigUpdated(tailnet, &oldConfig, eventlog.User(principal.User)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tailnet.ServiceCollectionEnabled = req.Msg.ServiceCollectionEnabled
|
tailnet.ServiceCollectionEnabled = req.Msg.ServiceCollectionEnabled
|
||||||
@@ -150,6 +178,7 @@ func (s *Service) UpdateTailnet(ctx context.Context, req *connect.Request[api.Up
|
|||||||
return nil, logError(err)
|
return nil, logError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eventlog.Send(ctx, events...)
|
||||||
s.sessionManager.NotifyAll(tailnet.ID)
|
s.sessionManager.NotifyAll(tailnet.ID)
|
||||||
|
|
||||||
t, err := domainTailnetToApiTailnet(tailnet)
|
t, err := domainTailnetToApiTailnet(tailnet)
|
||||||
|
|||||||
Reference in New Issue
Block a user