mirror of
https://github.com/juanfont/headscale.git
synced 2024-11-26 08:53:05 +00:00
Update protobuf definitions + support methods for the API
Add more logging Updated protos with new routes API
This commit is contained in:
parent
8170f5e693
commit
1b557ac1ea
3 changed files with 148 additions and 22 deletions
|
@ -126,17 +126,31 @@ service HeadscaleService {
|
|||
// --- Machine end ---
|
||||
|
||||
// --- Route start ---
|
||||
rpc GetMachineRoute(GetMachineRouteRequest) returns (GetMachineRouteResponse) {
|
||||
rpc GetRoutes(GetRoutesRequest) returns (GetRoutesResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/api/v1/routes"
|
||||
};
|
||||
}
|
||||
|
||||
rpc EnableRoute(EnableRouteRequest) returns (EnableRouteResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/api/v1/routes/{route_id}/enable"
|
||||
};
|
||||
}
|
||||
|
||||
rpc DisableRoute(DisableRouteRequest) returns (DisableRouteResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/api/v1/routes/{route_id}/disable"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
rpc GetMachineRoutes(GetMachineRoutesRequest) returns (GetMachineRoutesResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/api/v1/machine/{machine_id}/routes"
|
||||
};
|
||||
}
|
||||
|
||||
rpc EnableMachineRoutes(EnableMachineRoutesRequest) returns (EnableMachineRoutesResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/api/v1/machine/{machine_id}/routes"
|
||||
};
|
||||
}
|
||||
// --- Route end ---
|
||||
|
||||
// --- ApiKeys start ---
|
||||
|
|
|
@ -2,24 +2,47 @@ syntax = "proto3";
|
|||
package headscale.v1;
|
||||
option go_package = "github.com/juanfont/headscale/gen/go/v1";
|
||||
|
||||
message Routes {
|
||||
repeated string advertised_routes = 1;
|
||||
repeated string enabled_routes = 2;
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "headscale/v1/machine.proto";
|
||||
|
||||
message Route {
|
||||
uint64 id = 1;
|
||||
Machine machine = 2;
|
||||
string prefix = 3;
|
||||
bool advertised = 4;
|
||||
bool enabled = 5;
|
||||
bool is_primary = 6;
|
||||
|
||||
google.protobuf.Timestamp created_at = 7;
|
||||
google.protobuf.Timestamp updated_at = 8;
|
||||
google.protobuf.Timestamp deleted_at = 9;
|
||||
}
|
||||
|
||||
message GetMachineRouteRequest {
|
||||
message GetRoutesRequest {
|
||||
}
|
||||
|
||||
message GetRoutesResponse {
|
||||
repeated Route routes = 1;
|
||||
}
|
||||
|
||||
message EnableRouteRequest {
|
||||
uint64 route_id = 1;
|
||||
}
|
||||
|
||||
message EnableRouteResponse {
|
||||
}
|
||||
|
||||
message DisableRouteRequest {
|
||||
uint64 route_id = 1;
|
||||
}
|
||||
|
||||
message DisableRouteResponse {
|
||||
}
|
||||
|
||||
message GetMachineRoutesRequest {
|
||||
uint64 machine_id = 1;
|
||||
}
|
||||
|
||||
message GetMachineRouteResponse {
|
||||
Routes routes = 1;
|
||||
}
|
||||
|
||||
message EnableMachineRoutesRequest {
|
||||
uint64 machine_id = 1;
|
||||
repeated string routes = 2;
|
||||
}
|
||||
|
||||
message EnableMachineRoutesResponse {
|
||||
Routes routes = 1;
|
||||
}
|
||||
message GetMachineRoutesResponse {
|
||||
repeated Route routes = 1;
|
||||
}
|
89
routes.go
89
routes.go
|
@ -5,7 +5,9 @@ import (
|
|||
"fmt"
|
||||
"net/netip"
|
||||
|
||||
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
|
||||
"github.com/rs/zerolog/log"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
|
@ -49,6 +51,64 @@ func (rs Routes) toPrefixes() []netip.Prefix {
|
|||
return prefixes
|
||||
}
|
||||
|
||||
func (h *Headscale) GetRoutes() ([]Route, error) {
|
||||
var routes []Route
|
||||
err := h.db.Preload("Machine").Find(&routes).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return routes, nil
|
||||
}
|
||||
|
||||
func (h *Headscale) GetMachineRoutes(m *Machine) ([]Route, error) {
|
||||
var routes []Route
|
||||
err := h.db.
|
||||
Preload("Machine").
|
||||
Where("machine_id = ?", m.ID).
|
||||
Find(&routes).Error
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return routes, nil
|
||||
}
|
||||
|
||||
func (h *Headscale) GetRoute(id uint64) (*Route, error) {
|
||||
var route Route
|
||||
err := h.db.Preload("Machine").First(&route, id).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &route, nil
|
||||
}
|
||||
|
||||
func (h *Headscale) EnableRoute(id uint64) error {
|
||||
route, err := h.GetRoute(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return h.EnableRoutes(&route.Machine, netip.Prefix(route.Prefix).String())
|
||||
}
|
||||
|
||||
func (h *Headscale) DisableRoute(id uint64) error {
|
||||
route, err := h.GetRoute(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
route.Enabled = false
|
||||
route.IsPrimary = false
|
||||
err = h.db.Save(route).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return h.handlePrimarySubnetFailover()
|
||||
}
|
||||
|
||||
// isUniquePrefix returns if there is another machine providing the same route already.
|
||||
func (h *Headscale) isUniquePrefix(route Route) bool {
|
||||
var count int64
|
||||
|
@ -163,6 +223,10 @@ func (h *Headscale) handlePrimarySubnetFailover() error {
|
|||
if !route.IsPrimary {
|
||||
_, err := h.getPrimaryRoute(netip.Prefix(route.Prefix))
|
||||
if h.isUniquePrefix(route) || errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
log.Info().
|
||||
Str("prefix", netip.Prefix(route.Prefix).String()).
|
||||
Str("machine", route.Machine.GivenName).
|
||||
Msg("Setting primary route")
|
||||
routes[pos].IsPrimary = true
|
||||
err := h.db.Save(&routes[pos]).Error
|
||||
if err != nil {
|
||||
|
@ -247,3 +311,28 @@ func (h *Headscale) handlePrimarySubnetFailover() error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rs Routes) toProto() []*v1.Route {
|
||||
protoRoutes := []*v1.Route{}
|
||||
|
||||
for _, route := range rs {
|
||||
protoRoute := v1.Route{
|
||||
Id: uint64(route.ID),
|
||||
Machine: route.Machine.toProto(),
|
||||
Prefix: netip.Prefix(route.Prefix).String(),
|
||||
Advertised: route.Advertised,
|
||||
Enabled: route.Enabled,
|
||||
IsPrimary: route.IsPrimary,
|
||||
CreatedAt: timestamppb.New(route.CreatedAt),
|
||||
UpdatedAt: timestamppb.New(route.UpdatedAt),
|
||||
}
|
||||
|
||||
if route.DeletedAt.Valid {
|
||||
protoRoute.DeletedAt = timestamppb.New(route.DeletedAt.Time)
|
||||
}
|
||||
|
||||
protoRoutes = append(protoRoutes, &protoRoute)
|
||||
}
|
||||
|
||||
return protoRoutes
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue