diff --git a/internal/pkg/configuration/configuration.go b/internal/pkg/configuration/configuration.go index 998768a9ae..24af2936d1 100644 --- a/internal/pkg/configuration/configuration.go +++ b/internal/pkg/configuration/configuration.go @@ -66,7 +66,7 @@ func Generate(ctx context.Context, in *machine.GenerateConfigurationRequest) (re } } - options = append(options, generate.WithNetworkConfig(networkConfig)) + options = append(options, generate.WithNetworkOptions(v1alpha1.WithNetworkConfig(networkConfig))) } if in.MachineConfig.InstallConfig != nil { diff --git a/pkg/machinery/config/types/v1alpha1/generate/generate.go b/pkg/machinery/config/types/v1alpha1/generate/generate.go index 1de57ed83f..87142adf8f 100644 --- a/pkg/machinery/config/types/v1alpha1/generate/generate.go +++ b/pkg/machinery/config/types/v1alpha1/generate/generate.go @@ -77,8 +77,8 @@ type Input struct { InstallImage string InstallExtraKernelArgs []string - NetworkConfig *v1alpha1.NetworkConfig - CNIConfig *v1alpha1.CNIConfig + NetworkConfigOptions []v1alpha1.NetworkConfigOption + CNIConfig *v1alpha1.CNIConfig RegistryMirrors map[string]*v1alpha1.RegistryMirrorConfig RegistryConfig map[string]*v1alpha1.RegistryConfig @@ -450,10 +450,6 @@ func NewInput(clustername, endpoint, kubernetesVersion string, secrets *SecretsB additionalSubjectAltNames = append(additionalSubjectAltNames, options.AdditionalSubjectAltNames...) - if options.NetworkConfig == nil { - options.NetworkConfig = &v1alpha1.NetworkConfig{} - } - input = &Input{ Certs: secrets.Certs, ControlPlaneEndpoint: endpoint, @@ -469,7 +465,7 @@ func NewInput(clustername, endpoint, kubernetesVersion string, secrets *SecretsB InstallDisk: options.InstallDisk, InstallImage: options.InstallImage, InstallExtraKernelArgs: options.InstallExtraKernelArgs, - NetworkConfig: options.NetworkConfig, + NetworkConfigOptions: options.NetworkConfigOptions, CNIConfig: options.CNIConfig, RegistryMirrors: options.RegistryMirrors, RegistryConfig: options.RegistryConfig, diff --git a/pkg/machinery/config/types/v1alpha1/generate/init.go b/pkg/machinery/config/types/v1alpha1/generate/init.go index c615c02b62..4db4d06134 100644 --- a/pkg/machinery/config/types/v1alpha1/generate/init.go +++ b/pkg/machinery/config/types/v1alpha1/generate/init.go @@ -9,6 +9,7 @@ import ( "net/url" v1alpha1 "github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1" + "github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/machine" "github.com/talos-systems/talos/pkg/machinery/constants" ) @@ -19,12 +20,20 @@ func initUd(in *Input) (*v1alpha1.Config, error) { ConfigPersist: in.Persist, } + networkConfig := &v1alpha1.NetworkConfig{} + + for _, opt := range in.NetworkConfigOptions { + if err := opt(machine.TypeControlPlane, networkConfig); err != nil { + return nil, err + } + } + machine := &v1alpha1.MachineConfig{ MachineType: "init", MachineKubelet: &v1alpha1.KubeletConfig{ KubeletImage: emptyIf(fmt.Sprintf("%s:v%s", constants.KubeletImage, in.KubernetesVersion), in.KubernetesVersion), }, - MachineNetwork: in.NetworkConfig, + MachineNetwork: networkConfig, MachineCA: in.Certs.OS, MachineCertSANs: in.AdditionalMachineCertSANs, MachineToken: in.TrustdInfo.Token, diff --git a/pkg/machinery/config/types/v1alpha1/generate/join.go b/pkg/machinery/config/types/v1alpha1/generate/join.go index 4216b2a20e..7f05d139ea 100644 --- a/pkg/machinery/config/types/v1alpha1/generate/join.go +++ b/pkg/machinery/config/types/v1alpha1/generate/join.go @@ -11,6 +11,7 @@ import ( "github.com/talos-systems/crypto/x509" v1alpha1 "github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1" + "github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/machine" "github.com/talos-systems/talos/pkg/machinery/constants" ) @@ -21,6 +22,14 @@ func workerUd(in *Input) (*v1alpha1.Config, error) { ConfigPersist: in.Persist, } + networkConfig := &v1alpha1.NetworkConfig{} + + for _, opt := range in.NetworkConfigOptions { + if err := opt(machine.TypeJoin, networkConfig); err != nil { + return nil, err + } + } + machine := &v1alpha1.MachineConfig{ MachineType: "worker", MachineToken: in.TrustdInfo.Token, @@ -28,7 +37,7 @@ func workerUd(in *Input) (*v1alpha1.Config, error) { MachineKubelet: &v1alpha1.KubeletConfig{ KubeletImage: emptyIf(fmt.Sprintf("%s:v%s", constants.KubeletImage, in.KubernetesVersion), in.KubernetesVersion), }, - MachineNetwork: in.NetworkConfig, + MachineNetwork: networkConfig, MachineInstall: &v1alpha1.InstallConfig{ InstallDisk: in.InstallDisk, InstallImage: in.InstallImage, diff --git a/pkg/machinery/config/types/v1alpha1/generate/options.go b/pkg/machinery/config/types/v1alpha1/generate/options.go index 10f6e28c38..489b0d906d 100644 --- a/pkg/machinery/config/types/v1alpha1/generate/options.go +++ b/pkg/machinery/config/types/v1alpha1/generate/options.go @@ -57,10 +57,10 @@ func WithInstallExtraKernelArgs(args []string) GenOption { } } -// WithNetworkConfig allows to pass network config to be used. -func WithNetworkConfig(network *v1alpha1.NetworkConfig) GenOption { +// WithNetworkOptions adds network config generation option. +func WithNetworkOptions(opts ...v1alpha1.NetworkConfigOption) GenOption { return func(o *GenOptions) error { - o.NetworkConfig = network + o.NetworkConfigOptions = append(o.NetworkConfigOptions, opts...) return nil } @@ -179,7 +179,7 @@ type GenOptions struct { InstallImage string InstallExtraKernelArgs []string AdditionalSubjectAltNames []string - NetworkConfig *v1alpha1.NetworkConfig + NetworkConfigOptions []v1alpha1.NetworkConfigOption CNIConfig *v1alpha1.CNIConfig RegistryMirrors map[string]*v1alpha1.RegistryMirrorConfig RegistryConfig map[string]*v1alpha1.RegistryConfig diff --git a/pkg/machinery/config/types/v1alpha1/v1alpha1_network_options.go b/pkg/machinery/config/types/v1alpha1/v1alpha1_network_options.go new file mode 100644 index 0000000000..b4ca84eec9 --- /dev/null +++ b/pkg/machinery/config/types/v1alpha1/v1alpha1_network_options.go @@ -0,0 +1,107 @@ +// 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 v1alpha1 + +import ( + "github.com/AlekSi/pointer" + + "github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/machine" +) + +// NetworkConfigOption generates NetworkConfig. +type NetworkConfigOption func(machine.Type, *NetworkConfig) error + +// WithNetworkConfig sets whole network config structure, overwrites any previous options. +func WithNetworkConfig(c *NetworkConfig) NetworkConfigOption { + return func(_ machine.Type, cfg *NetworkConfig) error { + *cfg = *c + + return nil + } +} + +// WithNetworkNameservers sets global nameservers list. +func WithNetworkNameservers(nameservers ...string) NetworkConfigOption { + return func(_ machine.Type, cfg *NetworkConfig) error { + cfg.NameServers = append(cfg.NameServers, nameservers...) + + return nil + } +} + +// WithNetworkInterfaceIgnore marks interface as ignored. +func WithNetworkInterfaceIgnore(iface string) NetworkConfigOption { + return func(_ machine.Type, cfg *NetworkConfig) error { + cfg.GetDevice(iface).DeviceIgnore = true + + return nil + } +} + +// WithNetworkInterfaceDHCP enables DHCP for the interface. +func WithNetworkInterfaceDHCP(iface string, enable bool) NetworkConfigOption { + return func(_ machine.Type, cfg *NetworkConfig) error { + cfg.GetDevice(iface).DeviceDHCP = true + + return nil + } +} + +// WithNetworkInterfaceDHCPv4 enables DHCPv4 for the interface. +func WithNetworkInterfaceDHCPv4(iface string, enable bool) NetworkConfigOption { + return func(_ machine.Type, cfg *NetworkConfig) error { + dev := cfg.GetDevice(iface) + + if dev.DeviceDHCPOptions == nil { + dev.DeviceDHCPOptions = &DHCPOptions{} + } + + dev.DeviceDHCPOptions.DHCPIPv4 = pointer.ToBool(enable) + + return nil + } +} + +// WithNetworkInterfaceDHCPv6 enables DHCPv6 for the interface. +func WithNetworkInterfaceDHCPv6(iface string, enable bool) NetworkConfigOption { + return func(_ machine.Type, cfg *NetworkConfig) error { + dev := cfg.GetDevice(iface) + + if dev.DeviceDHCPOptions == nil { + dev.DeviceDHCPOptions = &DHCPOptions{} + } + + dev.DeviceDHCPOptions.DHCPIPv6 = pointer.ToBool(enable) + + return nil + } +} + +// WithNetworkInterfaceCIDR configures interface for static addressing. +func WithNetworkInterfaceCIDR(iface, cidr string) NetworkConfigOption { + return func(_ machine.Type, cfg *NetworkConfig) error { + cfg.GetDevice(iface).DeviceCIDR = cidr + + return nil + } +} + +// WithNetworkInterfaceMTU configures interface MTU. +func WithNetworkInterfaceMTU(iface string, mtu int) NetworkConfigOption { + return func(_ machine.Type, cfg *NetworkConfig) error { + cfg.GetDevice(iface).DeviceMTU = mtu + + return nil + } +} + +// WithNetworkInterfaceWireguard configures interface for Wireguard. +func WithNetworkInterfaceWireguard(iface string, wireguardConfig *DeviceWireguardConfig) NetworkConfigOption { + return func(_ machine.Type, cfg *NetworkConfig) error { + cfg.GetDevice(iface).DeviceWireguardConfig = wireguardConfig + + return nil + } +} diff --git a/pkg/machinery/config/types/v1alpha1/v1alpha1_provider.go b/pkg/machinery/config/types/v1alpha1/v1alpha1_provider.go index fd5464f687..73bf59cf31 100644 --- a/pkg/machinery/config/types/v1alpha1/v1alpha1_provider.go +++ b/pkg/machinery/config/types/v1alpha1/v1alpha1_provider.go @@ -764,6 +764,23 @@ func (n *NetworkConfig) Devices() []config.Device { return interfaces } +// GetDevice adds or returns existing Device by name. +func (n *NetworkConfig) GetDevice(name string) *Device { + for _, dev := range n.NetworkInterfaces { + if dev.DeviceInterface == name { + return dev + } + } + + dev := &Device{ + DeviceInterface: name, + } + + n.NetworkInterfaces = append(n.NetworkInterfaces, dev) + + return dev +} + // Resolvers implements the config.Provider interface. func (n *NetworkConfig) Resolvers() []string { return n.NameServers diff --git a/pkg/machinery/go.mod b/pkg/machinery/go.mod index eb9719edbc..60e2a5fa7a 100644 --- a/pkg/machinery/go.mod +++ b/pkg/machinery/go.mod @@ -3,6 +3,7 @@ module github.com/talos-systems/talos/pkg/machinery go 1.14 require ( + github.com/AlekSi/pointer v1.1.0 github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef github.com/containerd/containerd v1.4.1 github.com/containerd/go-cni v1.0.1 diff --git a/pkg/provision/providers/docker/docker.go b/pkg/provision/providers/docker/docker.go index e9c4108595..3bd505124a 100644 --- a/pkg/provision/providers/docker/docker.go +++ b/pkg/provision/providers/docker/docker.go @@ -67,7 +67,7 @@ func (p *provisioner) GenOptions(networkReq provision.NetworkRequest) []generate networkConfig.NameServers = nameservers } - ret = append(ret, generate.WithNetworkConfig(networkConfig)) + ret = append(ret, generate.WithNetworkOptions(v1alpha1.WithNetworkInterfaceIgnore("eth0"))) return ret } diff --git a/pkg/provision/providers/firecracker/firecracker.go b/pkg/provision/providers/firecracker/firecracker.go index ff449d551a..0b1774f1d2 100644 --- a/pkg/provision/providers/firecracker/firecracker.go +++ b/pkg/provision/providers/firecracker/firecracker.go @@ -55,16 +55,11 @@ func (p *provisioner) GenOptions(networkReq provision.NetworkRequest) []generate // Talos-specific "talos.platform=metal", }), - generate.WithNetworkConfig(&v1alpha1.NetworkConfig{ - NameServers: nameservers, - NetworkInterfaces: []*v1alpha1.Device{ - { - DeviceInterface: "eth0", - DeviceCIDR: "169.254.128.128/32", // link-local IP just to trigger the static networkd config - DeviceMTU: networkReq.MTU, - }, - }, - }), + generate.WithNetworkOptions( + v1alpha1.WithNetworkNameservers(nameservers...), + v1alpha1.WithNetworkInterfaceCIDR("eth0", "169.254.128.128/32"), // link-local IP just to trigger the static networkd config + v1alpha1.WithNetworkInterfaceMTU("eth0", networkReq.MTU), + ), } } diff --git a/pkg/provision/providers/qemu/qemu.go b/pkg/provision/providers/qemu/qemu.go index ebfbe07868..07742bebf3 100644 --- a/pkg/provision/providers/qemu/qemu.go +++ b/pkg/provision/providers/qemu/qemu.go @@ -7,8 +7,6 @@ package qemu import ( "context" - "github.com/AlekSi/pointer" - "github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1" "github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/generate" "github.com/talos-systems/talos/pkg/provision" @@ -59,19 +57,10 @@ func (p *provisioner) GenOptions(networkReq provision.NetworkRequest) []generate // Talos-specific "talos.platform=metal", }), - generate.WithNetworkConfig( - &v1alpha1.NetworkConfig{ - NetworkInterfaces: []*v1alpha1.Device{ - { - DeviceInterface: "eth0", - DeviceDHCP: true, - DeviceDHCPOptions: &v1alpha1.DHCPOptions{ - DHCPIPv4: pointer.ToBool(hasIPv4), - DHCPIPv6: pointer.ToBool(hasIPv6), - }, - }, - }, - }, + generate.WithNetworkOptions( + v1alpha1.WithNetworkInterfaceDHCP("eth0", true), + v1alpha1.WithNetworkInterfaceDHCPv4("eth0", hasIPv4), + v1alpha1.WithNetworkInterfaceDHCPv6("eth0", hasIPv6), ), } }