Skip to content

Commit

Permalink
add possibility to manage network interfaces with a template
Browse files Browse the repository at this point in the history
  • Loading branch information
trefzer committed Nov 12, 2024
1 parent 1fc5d99 commit 16dd60c
Show file tree
Hide file tree
Showing 94 changed files with 3,731 additions and 3 deletions.
2,071 changes: 2,071 additions & 0 deletions REFERENCE.md

Large diffs are not rendered by default.

80 changes: 77 additions & 3 deletions manifests/networkd.pp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,53 @@
# @param ensure The state that the ``networkd`` service should be in
# @param path path where all networkd files are placed in
# @param manage_all_network_files if enabled, all networkd files that aren't managed by puppet will be purged
# @param link_profiles
# Hash of network link profiles that can be referenced by it's key on an interface
# The structure is equal to the 'link' parameter of an interface.
# @param netdev_profiles
# Hash of netdev profiles that can be referenced by it's key on an interface
# The structure is equal to the 'netdev' parameter of an interface.
# @param network_profiles
# Hash of network profiles that can be referenced by it's key on an interface
# The structure is equal to the 'network' parameter of an interface.
# @param interfaces
# Hash of interfaces to configure on a node.
# The link, netdev and network parameters are deep merged with the respective profile
# (referenced by the key of the interface).
# With the profiles you can set the default values for a network.
# Hint: to remove a profile setting for an interface you can either overwrite or
# set it to '~' for removal.
# Example (hiera yaml notation):
# systemd::networkd::network_profiles:
# mynet:
# Network:
# Gateway: '192.168.0.1'
#
# systemd::networkd
# mynet:
# filename: '50-static'
# network:
# Match:
# Name: 'eno0'
# Network:
# Address: '192.168.0.15/24'
#
# Gives you a file /etc/systemd/network/50-static.network
# with content:
# [Match]
# Name=enp2s0
# [Network]
# Address=192.168.0.15/24
# Gateway=192.168.0.1
#
class systemd::networkd (
Enum['stopped','running'] $ensure = $systemd::networkd_ensure,
Stdlib::Absolutepath $path = $systemd::network_path,
Boolean $manage_all_network_files = $systemd::manage_all_network_files,
Enum['stopped','running'] $ensure = $systemd::networkd_ensure,
Stdlib::Absolutepath $path = $systemd::network_path,
Boolean $manage_all_network_files = $systemd::manage_all_network_files,
Hash[String[1],Systemd::Interface::Link] $link_profiles = {},
Hash[String[1],Systemd::Interface::Netdev] $netdev_profiles = {},
Hash[String[1],Systemd::Interface::Network] $network_profiles = {},
Hash[String[1],Systemd::Interface] $interfaces = {},
) {
assert_private()

Expand All @@ -32,4 +75,35 @@
notify => Service['systemd-networkd'],
}
}

$interfaces.each | String[1] $interface_name, Systemd::Interface $interface | {
$_filename=pick($interface['filename'], $interface_name)
if 'link' in $interface.keys() {
systemd::network { "${_filename}.link":
path => $path,
content => epp('systemd/network.epp', {
fname => "${_filename}.link",
config => deep_merge(pick($link_profiles[$interface_name], {}), $interface['link']),
}),
}
}
if 'netdev' in $interface.keys() {
systemd::network { "${_filename}.netdev":
path => $path,
content => epp('systemd/network.epp', {
fname => "${_filename}.netdev",
config => deep_merge(pick($netdev_profiles[$interface_name], {}), $interface['netdev']),
}),
}
}
if 'network' in $interface.keys() {
systemd::network { "${_filename}.network":
path => $path,
content => epp('systemd/network.epp', {
fname => "${_filename}.network",
config => deep_merge(pick($network_profiles[$interface_name], {}), $interface['network']),
}),
}
}
}
}
20 changes: 20 additions & 0 deletions spec/classes/networkd_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

require 'spec_helper'

describe 'systemd::networkd' do
on_supported_os.each do |os, os_facts|
context "on #{os}" do
let(:facts) { os_facts }
let(:pre_condition) do
[
'include systemd',
# Fake assert_private function from stdlib to not fail within this test
'function assert_private () { }',
]
end

it { is_expected.to compile.with_all_deps }
end
end
end
34 changes: 34 additions & 0 deletions spec/type_aliases/interface/link_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

require 'spec_helper'

describe 'Systemd::Interface::Link' do
describe 'valid types' do
context 'with valid types' do
[
{},
].each do |value|
describe value.inspect do
it { is_expected.to allow_value(value) }
end
end
end
end

describe 'invalid types' do
context 'with garbage inputs' do
[
true,
false,
:keyword,
nil,
{ 'foo' => 'bar' },
'42',
].each do |value|
describe value.inspect do
it { is_expected.not_to allow_value(value) }
end
end
end
end
end
34 changes: 34 additions & 0 deletions spec/type_aliases/interface/netdev_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

require 'spec_helper'

describe 'Systemd::Interface::Netdev' do
describe 'valid types' do
context 'with valid types' do
[
{},
].each do |value|
describe value.inspect do
it { is_expected.to allow_value(value) }
end
end
end
end

describe 'invalid types' do
context 'with garbage inputs' do
[
true,
false,
:keyword,
nil,
{ 'foo' => 'bar' },
'42',
].each do |value|
describe value.inspect do
it { is_expected.not_to allow_value(value) }
end
end
end
end
end
34 changes: 34 additions & 0 deletions spec/type_aliases/interface/network_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

require 'spec_helper'

describe 'Systemd::Interface::Network' do
describe 'valid types' do
context 'with valid types' do
[
{},
].each do |value|
describe value.inspect do
it { is_expected.to allow_value(value) }
end
end
end
end

describe 'invalid types' do
context 'with garbage inputs' do
[
true,
false,
:keyword,
nil,
{ 'foo' => 'bar' },
'42',
].each do |value|
describe value.inspect do
it { is_expected.not_to allow_value(value) }
end
end
end
end
end
34 changes: 34 additions & 0 deletions spec/type_aliases/systemd_interface_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

require 'spec_helper'

describe 'Systemd::Interface' do
describe 'valid types' do
context 'with valid types' do
[
{},
].each do |value|
describe value.inspect do
it { is_expected.to allow_value(value) }
end
end
end
end

describe 'invalid types' do
context 'with garbage inputs' do
[
true,
false,
:keyword,
nil,
{ 'foo' => 'bar' },
'42',
].each do |value|
describe value.inspect do
it { is_expected.not_to allow_value(value) }
end
end
end
end
end
26 changes: 26 additions & 0 deletions templates/network.epp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<%- | String[1] $fname = {},
Hash $config = {},
| -%>
#
# This file is managed with puppet
#
# File name: <%= $fname %>
#
<% $config.each |String $head, Variant[Hash,Array] $vals| { -%>
<%- if $vals =~ Array { $_loop= $vals } else { $_loop = [ $vals ] } -%>
<%- $_loop.each | Hash $vals | { -%>

<%- %>[<%= $head %>]
<%- $vals.each() | String $key, Any $value | { -%>
<%- if $value =~ Array[String] { -%>
<%- $value.each() | String $val | { -%>
<%- %><%= $key %>=<%= $val %>
<%- } -%>
<%- } else { -%>
<%- if $value !~ Undef { -%>
<%- %><%= $key %>=<%= $value %>
<%- } -%>
<%- } -%>
<%- } -%>
<%- } -%>
<% } -%>
7 changes: 7 additions & 0 deletions types/interface.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# network interface definition
type Systemd::Interface = Struct[{
filename => Optional[String[1]],
network => Optional[Systemd::Interface::Network],
netdev => Optional[Systemd::Interface::Netdev],
link => Optional[Systemd::Interface::Link],
}]
6 changes: 6 additions & 0 deletions types/interface/link.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# interface definition
type Systemd::Interface::Link = Struct[{
'Match' => Optional[Systemd::Interface::Link::Match],
'Link' => Optional[Systemd::Interface::Link::Link],
'SR-IOV' => Optional[Systemd::Interface::Link::Sr_iov],
}]
84 changes: 84 additions & 0 deletions types/interface/link/link.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# interface definition
type Systemd::Interface::Link::Link = Struct[{
'Description' => Optional[String[1]],
'Property' => Optional[String[1]],
'ImportProperty' => Optional[String[1]],
'UnsetProperty' => Optional[String[1]],
'Alias' => Optional[String[1]],
'MACAddressPolicy' => Optional[Enum['persistent', 'random', 'none', '']],
'MACAddress' => Optional[String[1]],
'NamePolicy' => Optional[Enum[
'kernel', 'database', 'onboard', 'slot',
'path', 'mac', 'keep'
]],
'Name' => Optional[String[1]],
'AlternativeNamesPolicy' => Optional[String[1]],
'AlternativeName' => Optional[String[1]],
'TransmitQueues' => Optional[Integer[1,4096]],
'ReceiveQueues' => Optional[Integer[1,4096]],
'TransmitQueueLength' => Optional[Integer[0, 4294967294]],
'MTUBytes' => Optional[Integer[1280]],
'BitsPerSecond' => Optional[String[1]],
'Duplex' => Optional[String[1]],
'AutoNegotiation' => Optional[Enum['yes','no']],
'WakeOnLan' => Optional[Enum[
'phy', 'unicast', 'multicast', 'broadcast',
'arp', 'magic', 'secureon'
]],
'WakeOnLanPassword' => Optional[String[1]],
'Port' => Optional[Enum['tp', 'aui', 'bnc', 'mii', 'fibre']],
'Advertise' => Optional[Variant[
Systemd::Interface::Link::Link_advertise,
Array[Systemd::Interface::Link::Link_advertise]
]],
'ReceiveChecksumOffload' => Optional[Enum['yes','no']],
'TransmitChecksumOffload' => Optional[Enum['yes','no']],
'TCPSegmentationOffload' => Optional[Enum['yes','no']],
'TCP6SegmentationOffload' => Optional[Enum['yes','no']],
'GenericSegmentationOffload' => Optional[Enum['yes','no']],
'GenericReceiveOffload' => Optional[Enum['yes','no']],
'LargeReceiveOffload' => Optional[Enum['yes','no']],
'ReceivePacketSteeringCPUMask' => Optional[String[1]],
'ReceiveVLANCTAGHardwareAcceleration' => Optional[Enum['yes','no']],
'TransmitVLANCTAGHardwareAcceleration'=> Optional[Enum['yes','no']],
'ReceiveVLANCTAGFilter' => Optional[Enum['yes','no']],
'TransmitVLANSTAGHardwareAcceleration'=> Optional[Enum['yes','no']],
'NTupleFilter' => Optional[Enum['yes','no']],
'RxChannels' => Optional[Variant[Enum['max'],Integer[1,4294967295]]],
'TxChannels' => Optional[Variant[Enum['max'],Integer[1,4294967295]]],
'OtherChannels' => Optional[Variant[Enum['max'],Integer[1,4294967295]]],
'CombinedChannels' => Optional[Variant[Enum['max'],Integer[1,4294967295]]],
'RxBufferSize' => Optional[Variant[Enum['max'],Integer[1,4294967295]]],
'RxMiniBufferSize' => Optional[Variant[Enum['max'],Integer[1,4294967295]]],
'RxJumboBufferSize' => Optional[Variant[Enum['max'],Integer[1,4294967295]]],
'TxBufferSize' => Optional[Variant[Enum['max'],Integer[1,4294967295]]],
'RxFlowControl' => Optional[Enum['yes','no']],
'TxFlowControl' => Optional[Enum['yes','no']],
'AutoNegotiationFlowControl' => Optional[Enum['yes','no']],
'GenericSegmentOffloadMaxBytes' => Optional[String[1]],
'GenericSegmentOffloadMaxSegments' => Optional[Integer[1, 65535]],
'UseAdaptiveRxCoalesce' => Optional[Enum['yes','no']],
'UseAdaptiveTxCoalesce' => Optional[Enum['yes','no']],
'RxCoalesceSec' => Optional[Integer],
'RxCoalesceIrqSec' => Optional[Integer],
'RxCoalesceLowSec' => Optional[Integer],
'RxCoalesceHighSec' => Optional[Integer],
'TxCoalesceSec' => Optional[Integer],
'TxCoalesceIrqSec' => Optional[Integer],
'TxCoalesceLowSec' => Optional[Integer],
'TxCoalesceHighSec' => Optional[Integer],
'RxMaxCoalescedFrames' => Optional[Integer],
'RxMaxCoalescedIrqFrames' => Optional[Integer],
'RxMaxCoalescedLowFrames' => Optional[Integer],
'RxMaxCoalescedHighFrames' => Optional[Integer],
'TxMaxCoalescedFrames' => Optional[Integer],
'TxMaxCoalescedIrqFrames' => Optional[Integer],
'TxMaxCoalescedLowFrames' => Optional[Integer],
'TxMaxCoalescedHighFrames' => Optional[Integer],
'CoalescePacketRateLow' => Optional[Integer],
'CoalescePacketRateHigh' => Optional[Integer],
'CoalescePacketRateSampleIntervalSec' => Optional[Integer],
'StatisticsBlockCoalesceSec' => Optional[Integer[1]],
'MDI' => Optional[Enum['straight', 'mdi', 'crossover', 'mdi-x', 'mdix', 'auto']],
'SR_IOVVirtualFunctions' => Optional[Integer[0, 2147483647]],
}]
Loading

0 comments on commit 16dd60c

Please sign in to comment.