mirror of
https://github.com/siderolabs/talos.git
synced 2025-12-01 23:51:50 +01:00
See #7230 This is a step towards preparing for multi-doc config. Split the `config.Provider` interface into parts which have different implementation: * `config.Config` accesses the config itself, it might be implemented by `v1alpha1.Config` for example * `config.Container` will be a set of config documents, which implement validation, encoding, etc. `Version()` method dropped, as it makes little sense and it was almost not used. `Raw()` method renamed to `RawV1Alpha1()` to support legacy direct access to `v1alpha1.Config`, next PR will refactor more to make it return proper type. There will be many more changes coming up. Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
117 lines
3.2 KiB
Go
117 lines
3.2 KiB
Go
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
package helpers
|
|
|
|
import (
|
|
"fmt"
|
|
"net/netip"
|
|
"strings"
|
|
"time"
|
|
|
|
sideronet "github.com/siderolabs/net"
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
|
|
"github.com/siderolabs/talos/pkg/machinery/config"
|
|
"github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1"
|
|
)
|
|
|
|
// NewWireguardConfigBundle creates a new Wireguard config bundle.
|
|
func NewWireguardConfigBundle(ips []netip.Addr, wireguardCidr string, listenPort, mastersCount int) (*WireguardConfigBundle, error) {
|
|
configs := map[string]*v1alpha1.Device{}
|
|
keys := make([]wgtypes.Key, len(ips))
|
|
peers := make([]*v1alpha1.DeviceWireguardPeer, len(ips))
|
|
|
|
for i, ip := range ips {
|
|
key, err := wgtypes.GeneratePrivateKey()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
keys[i] = key
|
|
|
|
peers[i] = &v1alpha1.DeviceWireguardPeer{
|
|
WireguardAllowedIPs: []string{
|
|
wireguardCidr,
|
|
},
|
|
WireguardPublicKey: key.PublicKey().String(),
|
|
WireguardPersistentKeepaliveInterval: time.Second * 5,
|
|
}
|
|
|
|
if i < mastersCount {
|
|
peers[i].WireguardEndpoint = fmt.Sprintf("%s:%d", ip.String(), listenPort)
|
|
}
|
|
}
|
|
|
|
parts := strings.Split(wireguardCidr, "/")
|
|
networkNumber := parts[1]
|
|
|
|
network, err := netip.ParsePrefix(wireguardCidr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for i, nodeIP := range ips {
|
|
wgIP, err := sideronet.NthIPInNetwork(network, i+2)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
config := &v1alpha1.DeviceWireguardConfig{}
|
|
|
|
currentPeers := []*v1alpha1.DeviceWireguardPeer{}
|
|
// add all peers except self
|
|
for _, peer := range peers {
|
|
if peer.PublicKey() != keys[i].PublicKey().String() {
|
|
currentPeers = append(currentPeers, peer)
|
|
}
|
|
}
|
|
|
|
config.WireguardPeers = currentPeers
|
|
config.WireguardPrivateKey = keys[i].String()
|
|
|
|
device := &v1alpha1.Device{
|
|
DeviceInterface: "wg0",
|
|
DeviceAddresses: []string{fmt.Sprintf("%s/%s", wgIP.String(), networkNumber)},
|
|
DeviceWireguardConfig: config,
|
|
DeviceMTU: 1500,
|
|
}
|
|
|
|
if i < mastersCount {
|
|
config.WireguardListenPort = listenPort
|
|
}
|
|
|
|
configs[nodeIP.String()] = device
|
|
}
|
|
|
|
return &WireguardConfigBundle{
|
|
configs: configs,
|
|
}, nil
|
|
}
|
|
|
|
// WireguardConfigBundle allows assembling wireguard network configuration with first controlplane being listen node.
|
|
type WireguardConfigBundle struct {
|
|
configs map[string]*v1alpha1.Device
|
|
}
|
|
|
|
// PatchConfig generates config patch for a node and patches the configuration data.
|
|
func (w *WireguardConfigBundle) PatchConfig(ip fmt.Stringer, cfg config.Provider) (config.Provider, error) {
|
|
config := cfg.RawV1Alpha1().(*v1alpha1.Config).DeepCopy()
|
|
|
|
if config.MachineConfig.MachineNetwork == nil {
|
|
config.MachineConfig.MachineNetwork = &v1alpha1.NetworkConfig{
|
|
NetworkInterfaces: []*v1alpha1.Device{},
|
|
}
|
|
}
|
|
|
|
device, ok := w.configs[ip.String()]
|
|
if !ok {
|
|
return nil, fmt.Errorf("failed to get wireguard config for node %s", ip.String())
|
|
}
|
|
|
|
config.MachineConfig.MachineNetwork.NetworkInterfaces = append(config.MachineConfig.MachineNetwork.NetworkInterfaces, device)
|
|
|
|
return config, nil
|
|
}
|