mirror of
https://github.com/jsiebens/ionscale.git
synced 2026-03-31 15:07:49 +01:00
feat: set and get derp map
This commit is contained in:
@@ -2,6 +2,7 @@ package broker
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/key"
|
||||
)
|
||||
|
||||
@@ -15,6 +16,7 @@ type Signal struct {
|
||||
PeersRemoved []uint64
|
||||
ACLUpdated bool
|
||||
DNSUpdated bool
|
||||
derpMap *tailcfg.DERPMap
|
||||
}
|
||||
|
||||
type Broker interface {
|
||||
@@ -26,6 +28,7 @@ type Broker interface {
|
||||
SignalPeersRemoved([]uint64)
|
||||
SignalDNSUpdated()
|
||||
SignalACLUpdated()
|
||||
SignalDERPMapUpdated(c *tailcfg.DERPMap)
|
||||
|
||||
IsConnected(uint64) bool
|
||||
}
|
||||
@@ -47,6 +50,14 @@ func (m *BrokerPool) Get(tailnetID uint64) Broker {
|
||||
return b
|
||||
}
|
||||
|
||||
func (m *BrokerPool) SignalDERPMapUpdated(c *tailcfg.DERPMap) {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
for _, b := range m.store {
|
||||
b.SignalDERPMapUpdated(c)
|
||||
}
|
||||
}
|
||||
|
||||
func newBroker(tailnetID uint64) Broker {
|
||||
b := &broker{
|
||||
tailnetID: tailnetID,
|
||||
@@ -103,6 +114,10 @@ func (h *broker) SignalACLUpdated() {
|
||||
h.signalChannel <- &Signal{ACLUpdated: true}
|
||||
}
|
||||
|
||||
func (h *broker) SignalDERPMapUpdated(c *tailcfg.DERPMap) {
|
||||
h.signalChannel <- &Signal{derpMap: c}
|
||||
}
|
||||
|
||||
func (h *broker) listen() {
|
||||
for {
|
||||
select {
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/jsiebens/ionscale/pkg/gen/api"
|
||||
"github.com/muesli/coral"
|
||||
"gopkg.in/yaml.v2"
|
||||
"io/ioutil"
|
||||
"tailscale.com/tailcfg"
|
||||
)
|
||||
|
||||
func derpMapCommand() *coral.Command {
|
||||
command := &coral.Command{
|
||||
Use: "derp-map",
|
||||
Short: "Manage DERP Map configuration",
|
||||
}
|
||||
|
||||
command.AddCommand(getDERPMap())
|
||||
command.AddCommand(setDERPMap())
|
||||
|
||||
return command
|
||||
}
|
||||
|
||||
func getDERPMap() *coral.Command {
|
||||
command := &coral.Command{
|
||||
Use: "get",
|
||||
Short: "Get the DERP Map configuration",
|
||||
SilenceUsage: true,
|
||||
}
|
||||
|
||||
var asJson bool
|
||||
|
||||
var target = Target{}
|
||||
target.prepareCommand(command)
|
||||
command.Flags().BoolVar(&asJson, "json", false, "")
|
||||
|
||||
command.RunE = func(command *coral.Command, args []string) error {
|
||||
client, c, err := target.createGRPCClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer safeClose(c)
|
||||
|
||||
resp, err := client.GetDERPMap(context.Background(), &api.GetDERPMapRequest{})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var derpMap struct {
|
||||
Regions map[int]*tailcfg.DERPRegion
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(resp.Value, &derpMap); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if asJson {
|
||||
marshal, err := json.MarshalIndent(derpMap, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Println(string(marshal))
|
||||
} else {
|
||||
marshal, err := yaml.Marshal(derpMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Println(string(marshal))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return command
|
||||
}
|
||||
|
||||
func setDERPMap() *coral.Command {
|
||||
command := &coral.Command{
|
||||
Use: "set",
|
||||
Short: "Set the DERP Map configuration",
|
||||
SilenceUsage: true,
|
||||
}
|
||||
|
||||
var file string
|
||||
var target = Target{}
|
||||
target.prepareCommand(command)
|
||||
command.Flags().StringVar(&file, "file", "", "")
|
||||
|
||||
command.RunE = func(command *coral.Command, args []string) error {
|
||||
grpcClient, c, err := target.createGRPCClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer safeClose(c)
|
||||
|
||||
rawJson, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := grpcClient.SetDERPMap(context.Background(), &api.SetDERPMapRequest{Value: rawJson})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var derpMap tailcfg.DERPMap
|
||||
if err := json.Unmarshal(resp.Value, &derpMap); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Println("DERP Map updated successfully")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
func Command() *coral.Command {
|
||||
rootCmd := rootCommand()
|
||||
rootCmd.AddCommand(keyCommand())
|
||||
rootCmd.AddCommand(derpMapCommand())
|
||||
rootCmd.AddCommand(serverCommand())
|
||||
rootCmd.AddCommand(versionCommand())
|
||||
rootCmd.AddCommand(tailnetCommand())
|
||||
|
||||
@@ -119,9 +119,6 @@ func (h *PollNetMapHandler) handleUpdate(c echo.Context, binder bind.Binder, m *
|
||||
keepAliveTicker := time.NewTicker(keepAliveInterval)
|
||||
syncTicker := time.NewTicker(5 * time.Second)
|
||||
|
||||
var latestSync = time.Now()
|
||||
var latestUpdate = latestSync
|
||||
|
||||
c.Response().WriteHeader(http.StatusOK)
|
||||
|
||||
if _, err := c.Response().Write(response); err != nil {
|
||||
@@ -137,6 +134,9 @@ func (h *PollNetMapHandler) handleUpdate(c echo.Context, binder bind.Binder, m *
|
||||
h.scheduleOfflineMessage(tailnetID, machineID)
|
||||
}()
|
||||
|
||||
var latestSync = time.Now()
|
||||
var latestUpdate = latestSync
|
||||
|
||||
for {
|
||||
select {
|
||||
case s := <-updateChan:
|
||||
@@ -292,6 +292,7 @@ func (h *PollNetMapHandler) createMapResponse(m *domain.Machine, binder bind.Bin
|
||||
} else {
|
||||
mapResponse = &tailcfg.MapResponse{
|
||||
PacketFilter: rules,
|
||||
DERPMap: derpMap,
|
||||
PeersChanged: changedPeers,
|
||||
PeersRemoved: removedPeers,
|
||||
UserProfiles: mapping.ToUserProfiles(users),
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/jsiebens/ionscale/pkg/gen/api"
|
||||
"tailscale.com/tailcfg"
|
||||
)
|
||||
|
||||
func (s *Service) GetDERPMap(ctx context.Context, req *api.GetDERPMapRequest) (*api.GetDERPMapResponse, error) {
|
||||
derpMap, err := s.repository.GetDERPMap(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
raw, err := json.Marshal(derpMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &api.GetDERPMapResponse{Value: raw}, nil
|
||||
}
|
||||
|
||||
func (s *Service) SetDERPMap(ctx context.Context, req *api.SetDERPMapRequest) (*api.SetDERPMapResponse, error) {
|
||||
var derpMap tailcfg.DERPMap
|
||||
err := json.Unmarshal(req.Value, &derpMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.repository.SetDERPMap(ctx, &derpMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.brokerPool.SignalDERPMapUpdated(&derpMap)
|
||||
|
||||
return &api.SetDERPMapResponse{Value: req.Value}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user