Make nebula config generation deterministic
This commit is contained in:
parent
e750bc44a5
commit
b4a58d1508
@ -8,6 +8,7 @@ import (
|
|||||||
"isle/daemon/daecommon"
|
"isle/daemon/daecommon"
|
||||||
"isle/nebula"
|
"isle/nebula"
|
||||||
"isle/toolkit"
|
"isle/toolkit"
|
||||||
|
"isle/yamlutil"
|
||||||
"net"
|
"net"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -51,19 +52,18 @@ func waitForNebula(
|
|||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO this needs to be produce a deterministic config value.
|
|
||||||
func nebulaConfig(
|
func nebulaConfig(
|
||||||
networkConfig daecommon.NetworkConfig,
|
networkConfig daecommon.NetworkConfig,
|
||||||
hostBootstrap bootstrap.Bootstrap,
|
hostBootstrap bootstrap.Bootstrap,
|
||||||
) (
|
) (
|
||||||
map[string]any, error,
|
any, error,
|
||||||
) {
|
) {
|
||||||
var (
|
var (
|
||||||
lighthouseHostIPs []string
|
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 == "" {
|
if host.Nebula.PublicAddr == "" {
|
||||||
continue
|
continue
|
||||||
@ -105,18 +105,20 @@ func nebulaConfig(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
config := map[string]any{
|
type m = yamlutil.OrderedMap[string, any]
|
||||||
"pki": map[string]string{
|
|
||||||
|
config := m{
|
||||||
|
"pki": m{
|
||||||
"ca": string(caCertPEM),
|
"ca": string(caCertPEM),
|
||||||
"cert": string(hostCertPEM),
|
"cert": string(hostCertPEM),
|
||||||
"key": string(hostKeyPEM),
|
"key": string(hostKeyPEM),
|
||||||
},
|
},
|
||||||
"static_host_map": staticHostMap,
|
"static_host_map": staticHostMap,
|
||||||
"punchy": map[string]bool{
|
"punchy": m{
|
||||||
"punch": true,
|
"punch": true,
|
||||||
"respond": true,
|
"respond": true,
|
||||||
},
|
},
|
||||||
"tun": map[string]any{
|
"tun": m{
|
||||||
"dev": nebula.GetDeviceName(hostBootstrap.NetworkCreationParams.ID),
|
"dev": nebula.GetDeviceName(hostBootstrap.NetworkCreationParams.ID),
|
||||||
},
|
},
|
||||||
"firewall": firewall,
|
"firewall": firewall,
|
||||||
@ -124,12 +126,12 @@ func nebulaConfig(
|
|||||||
|
|
||||||
if publicAddr := networkConfig.VPN.PublicAddr; publicAddr == "" {
|
if publicAddr := networkConfig.VPN.PublicAddr; publicAddr == "" {
|
||||||
|
|
||||||
config["listen"] = map[string]string{
|
config["listen"] = m{
|
||||||
"host": "0.0.0.0",
|
"host": "0.0.0.0",
|
||||||
"port": "0",
|
"port": "0",
|
||||||
}
|
}
|
||||||
|
|
||||||
config["lighthouse"] = map[string]any{
|
config["lighthouse"] = m{
|
||||||
"hosts": lighthouseHostIPs,
|
"hosts": lighthouseHostIPs,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,12 +151,12 @@ func nebulaConfig(
|
|||||||
host = "0.0.0.0"
|
host = "0.0.0.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
config["listen"] = map[string]string{
|
config["listen"] = m{
|
||||||
"host": host,
|
"host": host,
|
||||||
"port": port,
|
"port": port,
|
||||||
}
|
}
|
||||||
|
|
||||||
config["lighthouse"] = map[string]any{
|
config["lighthouse"] = m{
|
||||||
"hosts": []string{},
|
"hosts": []string{},
|
||||||
"am_lighthouse": true,
|
"am_lighthouse": true,
|
||||||
}
|
}
|
||||||
|
39
go/yamlutil/ordered_map.go
Normal file
39
go/yamlutil/ordered_map.go
Normal 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
|
||||||
|
}
|
20
go/yamlutil/ordered_map_test.go
Normal file
20
go/yamlutil/ordered_map_test.go
Normal 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))
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user