mirror of
https://github.com/jsiebens/ionscale.git
synced 2026-03-31 15:07:49 +01:00
169 lines
4.3 KiB
Go
169 lines
4.3 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/bufbuild/connect-go"
|
|
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
"inet.af/netaddr"
|
|
"time"
|
|
)
|
|
|
|
func (s *Service) ListMachines(ctx context.Context, req *connect.Request[api.ListMachinesRequest]) (*connect.Response[api.ListMachinesResponse], error) {
|
|
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if tailnet == nil {
|
|
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
|
|
}
|
|
|
|
machines, err := s.repository.ListMachineByTailnet(ctx, tailnet.ID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
response := &api.ListMachinesResponse{}
|
|
for _, m := range machines {
|
|
var name = m.Name
|
|
if m.NameIdx != 0 {
|
|
name = fmt.Sprintf("%s-%d", m.Name, m.NameIdx)
|
|
}
|
|
online := s.brokers(m.TailnetID).IsConnected(m.ID)
|
|
var lastSeen *timestamppb.Timestamp
|
|
if m.LastSeen != nil {
|
|
lastSeen = timestamppb.New(*m.LastSeen)
|
|
}
|
|
response.Machines = append(response.Machines, &api.Machine{
|
|
Id: m.ID,
|
|
Name: name,
|
|
Ipv4: m.IPv4.String(),
|
|
Ipv6: m.IPv6.String(),
|
|
Ephemeral: m.Ephemeral,
|
|
Tags: m.Tags,
|
|
LastSeen: lastSeen,
|
|
Connected: online,
|
|
Tailnet: &api.Ref{
|
|
Id: m.Tailnet.ID,
|
|
Name: m.Tailnet.Name,
|
|
},
|
|
User: &api.Ref{
|
|
Id: m.User.ID,
|
|
Name: m.User.Name,
|
|
},
|
|
})
|
|
}
|
|
|
|
return connect.NewResponse(response), nil
|
|
}
|
|
|
|
func (s *Service) DeleteMachine(ctx context.Context, req *connect.Request[api.DeleteMachineRequest]) (*connect.Response[api.DeleteMachineResponse], error) {
|
|
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if m == nil {
|
|
return nil, connect.NewError(connect.CodeNotFound, errors.New("machine not found"))
|
|
}
|
|
|
|
if _, err := s.repository.DeleteMachine(ctx, req.Msg.MachineId); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
s.brokers(m.TailnetID).SignalPeersRemoved([]uint64{m.ID})
|
|
|
|
return connect.NewResponse(&api.DeleteMachineResponse{}), nil
|
|
}
|
|
|
|
func (s *Service) ExpireMachine(ctx context.Context, req *connect.Request[api.ExpireMachineRequest]) (*connect.Response[api.ExpireMachineResponse], error) {
|
|
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if m == nil {
|
|
return nil, connect.NewError(connect.CodeNotFound, errors.New("machine not found"))
|
|
}
|
|
|
|
timestamp := time.Unix(123, 0)
|
|
m.ExpiresAt = ×tamp
|
|
|
|
if err := s.repository.SaveMachine(ctx, m); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
s.brokers(m.TailnetID).SignalPeerUpdated(m.ID)
|
|
|
|
return connect.NewResponse(&api.ExpireMachineResponse{}), nil
|
|
}
|
|
|
|
func (s *Service) GetMachineRoutes(ctx context.Context, req *connect.Request[api.GetMachineRoutesRequest]) (*connect.Response[api.GetMachineRoutesResponse], error) {
|
|
|
|
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if m == nil {
|
|
return nil, connect.NewError(connect.CodeNotFound, errors.New("machine not found"))
|
|
}
|
|
|
|
var routes []*api.RoutableIP
|
|
for _, r := range m.HostInfo.RoutableIPs {
|
|
routes = append(routes, &api.RoutableIP{
|
|
Advertised: r.String(),
|
|
Allowed: m.IsAllowedIPPrefix(r),
|
|
})
|
|
}
|
|
|
|
response := api.GetMachineRoutesResponse{
|
|
Routes: routes,
|
|
}
|
|
|
|
return connect.NewResponse(&response), nil
|
|
}
|
|
|
|
func (s *Service) SetMachineRoutes(ctx context.Context, req *connect.Request[api.SetMachineRoutesRequest]) (*connect.Response[api.GetMachineRoutesResponse], error) {
|
|
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if m == nil {
|
|
return nil, connect.NewError(connect.CodeNotFound, errors.New("machine not found"))
|
|
}
|
|
|
|
var allowedIps []netaddr.IPPrefix
|
|
for _, r := range req.Msg.AllowedIps {
|
|
prefix, err := netaddr.ParseIPPrefix(r)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
allowedIps = append(allowedIps, prefix)
|
|
}
|
|
|
|
m.AllowIPs = allowedIps
|
|
if err := s.repository.SaveMachine(ctx, m); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
s.brokers(m.TailnetID).SignalPeerUpdated(m.ID)
|
|
|
|
var routes []*api.RoutableIP
|
|
for _, r := range m.HostInfo.RoutableIPs {
|
|
routes = append(routes, &api.RoutableIP{
|
|
Advertised: r.String(),
|
|
Allowed: m.IsAllowedIPPrefix(r),
|
|
})
|
|
}
|
|
|
|
response := api.GetMachineRoutesResponse{
|
|
Routes: routes,
|
|
}
|
|
|
|
return connect.NewResponse(&response), nil
|
|
}
|