feat: add methods to enable and disable single routes

This commit is contained in:
Johan Siebens
2022-09-16 11:33:14 +02:00
parent f71ca49693
commit 3b9ce04ec8
10 changed files with 512 additions and 237 deletions
+80 -28
View File
@@ -21,13 +21,23 @@ func (s *Service) machineToApi(m *domain.Machine) *api.Machine {
if m.NameIdx != 0 {
name = fmt.Sprintf("%s-%d", m.Name, m.NameIdx)
}
// TODO connected?
online := false
if m.LastSeen != nil {
lastSeen = timestamppb.New(*m.LastSeen)
online = m.LastSeen.After(time.Now().Add(-config.KeepAliveInterval))
}
var advertisedRoutes []string
for _, r := range m.HostInfo.RoutableIPs {
advertisedRoutes = append(advertisedRoutes, r.String())
}
var enabledRoutes []string
for _, r := range m.AllowIPs {
enabledRoutes = append(enabledRoutes, r.String())
}
return &api.Machine{
Id: m.ID,
Name: name,
@@ -53,6 +63,8 @@ func (s *Service) machineToApi(m *domain.Machine) *api.Machine {
ClientConnectivity: &api.ClientConnectivity{
Endpoints: m.Endpoints,
},
AdvertisedRoutes: advertisedRoutes,
EnabledRoutes: enabledRoutes,
}
}
@@ -156,6 +168,25 @@ func (s *Service) ExpireMachine(ctx context.Context, req *connect.Request[api.Ex
return connect.NewResponse(&api.ExpireMachineResponse{}), nil
}
func (s *Service) createMachineRoutesResponse(m *domain.Machine) (*connect.Response[api.GetMachineRoutesResponse], error) {
var advertisedRoutes []string
for _, r := range m.HostInfo.RoutableIPs {
advertisedRoutes = append(advertisedRoutes, r.String())
}
var enabledRoutes []string
for _, r := range m.AllowIPs {
enabledRoutes = append(enabledRoutes, r.String())
}
response := api.GetMachineRoutesResponse{
AdvertisedRoutes: advertisedRoutes,
EnabledRoutes: enabledRoutes,
}
return connect.NewResponse(&response), nil
}
func (s *Service) GetMachineRoutes(ctx context.Context, req *connect.Request[api.GetMachineRoutesRequest]) (*connect.Response[api.GetMachineRoutesResponse], error) {
principal := CurrentPrincipal(ctx)
@@ -172,22 +203,10 @@ func (s *Service) GetMachineRoutes(ctx context.Context, req *connect.Request[api
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
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
return s.createMachineRoutesResponse(m)
}
func (s *Service) SetMachineRoutes(ctx context.Context, req *connect.Request[api.SetMachineRoutesRequest]) (*connect.Response[api.GetMachineRoutesResponse], error) {
func (s *Service) EnableMachineRoutes(ctx context.Context, req *connect.Request[api.EnableMachineRoutesRequest]) (*connect.Response[api.GetMachineRoutesResponse], error) {
principal := CurrentPrincipal(ctx)
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
@@ -203,35 +222,68 @@ func (s *Service) SetMachineRoutes(ctx context.Context, req *connect.Request[api
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
var allowedIps []netip.Prefix
for _, r := range req.Msg.AllowedIps {
var enabledRoutes = domain.NewAllowIPsSet(m.AllowIPs)
if req.Msg.Replace {
enabledRoutes = domain.NewAllowIPsSet([]netip.Prefix{})
}
var routesToBeRemoved []netip.Prefix
for _, r := range req.Msg.Routes {
prefix, err := netip.ParsePrefix(r)
if err != nil {
return nil, err
}
allowedIps = append(allowedIps, prefix)
enabledRoutes.Add(prefix)
routesToBeRemoved = append(routesToBeRemoved, prefix)
}
m.AllowIPs = allowedIps
m.AllowIPs = enabledRoutes.Items()
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, err
}
s.pubsub.Publish(m.TailnetID, &broker.Signal{PeerUpdated: &m.ID})
var routes []*api.RoutableIP
for _, r := range m.HostInfo.RoutableIPs {
routes = append(routes, &api.RoutableIP{
Advertised: r.String(),
Allowed: m.IsAllowedIPPrefix(r),
})
return s.createMachineRoutesResponse(m)
}
func (s *Service) DisableMachineRoutes(ctx context.Context, req *connect.Request[api.DisableMachineRoutesRequest]) (*connect.Response[api.GetMachineRoutesResponse], error) {
principal := CurrentPrincipal(ctx)
m, err := s.repository.GetMachine(ctx, req.Msg.MachineId)
if err != nil {
return nil, err
}
response := api.GetMachineRoutesResponse{
Routes: routes,
if m == nil {
return nil, connect.NewError(connect.CodeNotFound, errors.New("machine not found"))
}
return connect.NewResponse(&response), nil
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(m.TailnetID) {
return nil, connect.NewError(connect.CodePermissionDenied, errors.New("permission denied"))
}
enabledRoutes := domain.NewAllowIPsSet(m.AllowIPs)
var routesToBeRemoved []netip.Prefix
for _, r := range req.Msg.Routes {
prefix, err := netip.ParsePrefix(r)
if err != nil {
return nil, err
}
enabledRoutes.Remove(prefix)
routesToBeRemoved = append(routesToBeRemoved, prefix)
}
m.AllowIPs = enabledRoutes.Items()
if err := s.repository.SaveMachine(ctx, m); err != nil {
return nil, err
}
s.pubsub.Publish(m.TailnetID, &broker.Signal{PeerUpdated: &m.ID})
return s.createMachineRoutesResponse(m)
}
func (s *Service) SetMachineKeyExpiry(ctx context.Context, req *connect.Request[api.SetMachineKeyExpiryRequest]) (*connect.Response[api.SetMachineKeyExpiryResponse], error) {