Make nebula config generation deterministic

This commit is contained in:
Brian Picciano 2024-12-12 20:51:13 +01:00
parent e750bc44a5
commit b4a58d1508
3 changed files with 73 additions and 12 deletions

View File

@ -8,6 +8,7 @@ import (
"isle/daemon/daecommon"
"isle/nebula"
"isle/toolkit"
"isle/yamlutil"
"net"
"path/filepath"
"strconv"
@ -51,19 +52,18 @@ func waitForNebula(
return ctx.Err()
}
// TODO this needs to be produce a deterministic config value.
func nebulaConfig(
networkConfig daecommon.NetworkConfig,
hostBootstrap bootstrap.Bootstrap,
) (
map[string]any, error,
any, error,
) {
var (
lighthouseHostIPs []string
staticHostMap = map[string][]string{}
staticHostMap = yamlutil.OrderedMap[string, []string]{}
)
for _, host := range hostBootstrap.Hosts {
for _, host := range hostBootstrap.HostsOrdered() {
if host.Nebula.PublicAddr == "" {
continue
@ -105,18 +105,20 @@ func nebulaConfig(
)
}
config := map[string]any{
"pki": map[string]string{
type m = yamlutil.OrderedMap[string, any]
config := m{
"pki": m{
"ca": string(caCertPEM),
"cert": string(hostCertPEM),
"key": string(hostKeyPEM),
},
"static_host_map": staticHostMap,
"punchy": map[string]bool{
"punchy": m{
"punch": true,
"respond": true,
},
"tun": map[string]any{
"tun": m{
"dev": nebula.GetDeviceName(hostBootstrap.NetworkCreationParams.ID),
},
"firewall": firewall,
@ -124,12 +126,12 @@ func nebulaConfig(
if publicAddr := networkConfig.VPN.PublicAddr; publicAddr == "" {
config["listen"] = map[string]string{
config["listen"] = m{
"host": "0.0.0.0",
"port": "0",
}
config["lighthouse"] = map[string]any{
config["lighthouse"] = m{
"hosts": lighthouseHostIPs,
}
@ -149,12 +151,12 @@ func nebulaConfig(
host = "0.0.0.0"
}
config["listen"] = map[string]string{
config["listen"] = m{
"host": host,
"port": port,
}
config["lighthouse"] = map[string]any{
config["lighthouse"] = m{
"hosts": []string{},
"am_lighthouse": true,
}

View File

@ -0,0 +1,39 @@
package yamlutil
import (
"cmp"
"slices"
"gopkg.in/yaml.v3"
)
// OrderedMap is like a normal map, except that when it is marshaled to yaml it
// will do so with its keys in ascending order. This makes it useful when
// generating output which needs to be deterministic.
type OrderedMap[K comparable, V any] map[K]V
func (m OrderedMap[K, V]) MarshalYAML() (any, error) {
type wrapped map[K]V
var n yaml.Node
if err := n.Encode(wrapped(m)); err != nil {
return nil, err
}
pairs := make([][2]*yaml.Node, len(n.Content)/2)
for i := range pairs {
pairs[i][0] = n.Content[i*2]
pairs[i][1] = n.Content[i*2+1]
}
slices.SortFunc(pairs, func(a, b [2]*yaml.Node) int {
return cmp.Compare(a[0].Value, b[0].Value)
})
for i := range pairs {
n.Content[i*2] = pairs[i][0]
n.Content[i*2+1] = pairs[i][1]
}
return n, nil
}

View File

@ -0,0 +1,20 @@
package yamlutil
import (
"testing"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
)
func TestOrderedMap(t *testing.T) {
m := OrderedMap[string, int]{
"a": 1,
"b": 2,
"c": 3,
}
b, err := yaml.Marshal(m)
assert.NoError(t, err)
assert.Equal(t, "a: 1\nb: 2\nc: 3\n", string(b))
}