mirror of
https://github.com/fosrl/newt.git
synced 2026-03-09 20:26:45 +00:00
Add blueprint yaml sending
This commit is contained in:
1
go.mod
1
go.mod
@@ -51,4 +51,5 @@ require (
|
|||||||
golang.org/x/sys v0.35.0 // indirect
|
golang.org/x/sys v0.35.0 // indirect
|
||||||
golang.org/x/time v0.12.0 // indirect
|
golang.org/x/time v0.12.0 // indirect
|
||||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
1
go.sum
1
go.sum
@@ -161,6 +161,7 @@ google.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA=
|
|||||||
google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
|
google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
|
||||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
|
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
|
||||||
|
|||||||
35
main.go
35
main.go
@@ -74,6 +74,11 @@ type ExitNodePingResult struct {
|
|||||||
WasPreviouslyConnected bool `json:"wasPreviouslyConnected"`
|
WasPreviouslyConnected bool `json:"wasPreviouslyConnected"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BlueprintResult struct {
|
||||||
|
Success bool `json:"success"`
|
||||||
|
Message string `json:"message,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// Custom flag type for multiple CA files
|
// Custom flag type for multiple CA files
|
||||||
type stringSlice []string
|
type stringSlice []string
|
||||||
|
|
||||||
@@ -115,6 +120,7 @@ var (
|
|||||||
preferEndpoint string
|
preferEndpoint string
|
||||||
healthMonitor *healthcheck.Monitor
|
healthMonitor *healthcheck.Monitor
|
||||||
enforceHealthcheckCert bool
|
enforceHealthcheckCert bool
|
||||||
|
blueprintFile string
|
||||||
|
|
||||||
// New mTLS configuration variables
|
// New mTLS configuration variables
|
||||||
tlsClientCert string
|
tlsClientCert string
|
||||||
@@ -172,6 +178,7 @@ func main() {
|
|||||||
if tlsPrivateKey == "" {
|
if tlsPrivateKey == "" {
|
||||||
tlsPrivateKey = os.Getenv("TLS_CLIENT_CERT")
|
tlsPrivateKey = os.Getenv("TLS_CLIENT_CERT")
|
||||||
}
|
}
|
||||||
|
blueprintFile = os.Getenv("BLUEPRINT_FILE")
|
||||||
|
|
||||||
if endpoint == "" {
|
if endpoint == "" {
|
||||||
flag.StringVar(&endpoint, "endpoint", "", "Endpoint of your pangolin server")
|
flag.StringVar(&endpoint, "endpoint", "", "Endpoint of your pangolin server")
|
||||||
@@ -271,6 +278,9 @@ func main() {
|
|||||||
if healthFile == "" {
|
if healthFile == "" {
|
||||||
flag.StringVar(&healthFile, "health-file", "", "Path to health file (if unset, health file won't be written)")
|
flag.StringVar(&healthFile, "health-file", "", "Path to health file (if unset, health file won't be written)")
|
||||||
}
|
}
|
||||||
|
if blueprintFile == "" {
|
||||||
|
flag.StringVar(&blueprintFile, "blueprint-file", "", "Path to blueprint file (if unset, no blueprint will be applied)")
|
||||||
|
}
|
||||||
|
|
||||||
// do a --version check
|
// do a --version check
|
||||||
version := flag.Bool("version", false, "Print the version")
|
version := flag.Bool("version", false, "Print the version")
|
||||||
@@ -1193,6 +1203,29 @@ persistent_keepalive_interval=5`, fixKey(privateKey.String()), fixKey(wgData.Pub
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Register handler for getting health check status
|
||||||
|
client.RegisterHandler("newt/blueprint/results", func(msg websocket.WSMessage) {
|
||||||
|
logger.Debug("Received blueprint results message")
|
||||||
|
|
||||||
|
var blueprintResult BlueprintResult
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(msg.Data)
|
||||||
|
if err != nil {
|
||||||
|
logger.Info("Error marshaling data: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(jsonData, &blueprintResult); err != nil {
|
||||||
|
logger.Info("Error unmarshaling config results data: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if blueprintResult.Success {
|
||||||
|
logger.Info("Blueprint applied successfully!")
|
||||||
|
} else {
|
||||||
|
logger.Warn("Blueprint application failed: %s", blueprintResult.Message)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
client.OnConnect(func() error {
|
client.OnConnect(func() error {
|
||||||
publicKey = privateKey.PublicKey()
|
publicKey = privateKey.PublicKey()
|
||||||
logger.Debug("Public key: %s", publicKey)
|
logger.Debug("Public key: %s", publicKey)
|
||||||
@@ -1216,6 +1249,8 @@ persistent_keepalive_interval=5`, fixKey(privateKey.String()), fixKey(wgData.Pub
|
|||||||
"backwardsCompatible": true,
|
"backwardsCompatible": true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
sendBlueprint(client)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("Failed to send registration message: %v", err)
|
logger.Error("Failed to send registration message: %v", err)
|
||||||
return err
|
return err
|
||||||
|
|||||||
45
util.go
45
util.go
@@ -21,6 +21,7 @@ import (
|
|||||||
"golang.org/x/net/ipv4"
|
"golang.org/x/net/ipv4"
|
||||||
"golang.zx2c4.com/wireguard/device"
|
"golang.zx2c4.com/wireguard/device"
|
||||||
"golang.zx2c4.com/wireguard/tun/netstack"
|
"golang.zx2c4.com/wireguard/tun/netstack"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func fixKey(key string) string {
|
func fixKey(key string) string {
|
||||||
@@ -558,3 +559,47 @@ func executeUpdownScript(action, proto, target string) (string, error) {
|
|||||||
|
|
||||||
return target, nil
|
return target, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sendBlueprint(client *websocket.Client) error {
|
||||||
|
if blueprintFile == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// try to read the blueprint file
|
||||||
|
blueprintData, err := os.ReadFile(blueprintFile)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Failed to read blueprint file: %v", err)
|
||||||
|
} else {
|
||||||
|
// first we should convert the yaml to json and error if the yaml is bad
|
||||||
|
var yamlObj interface{}
|
||||||
|
var blueprintJsonData string
|
||||||
|
|
||||||
|
err = yaml.Unmarshal(blueprintData, &yamlObj)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Failed to parse blueprint YAML: %v", err)
|
||||||
|
} else {
|
||||||
|
// convert to json
|
||||||
|
jsonBytes, err := json.Marshal(yamlObj)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Failed to convert blueprint to JSON: %v", err)
|
||||||
|
} else {
|
||||||
|
blueprintJsonData = string(jsonBytes)
|
||||||
|
logger.Debug("Converted blueprint to JSON: %s", blueprintJsonData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we have valid json data, we can send it to the server
|
||||||
|
if blueprintJsonData == "" {
|
||||||
|
logger.Error("No valid blueprint JSON data to send to server")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info("Sending blueprint to server for application")
|
||||||
|
|
||||||
|
// send the blueprint data to the server
|
||||||
|
err = client.SendMessage("newt/blueprint/apply", map[string]interface{}{
|
||||||
|
"blueprint": blueprintJsonData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user